Skip to content

Comments

Logic: Rewrite mkAnd/mkOr to avoid memory allocations and term lookup#504

Open
blishko wants to merge 3 commits intomasterfrom
and-or
Open

Logic: Rewrite mkAnd/mkOr to avoid memory allocations and term lookup#504
blishko wants to merge 3 commits intomasterfrom
and-or

Conversation

@blishko
Copy link
Member

@blishko blishko commented May 27, 2022

This PR suggests to change the simplification code of mkAnd and mkOr methods.
It uses slightly more complicated comparison method for sorting the arguments, but the benefits are

  1. No auxiliary vector needed to store copy of the arguments
  2. Even more importantly, it avoids relatively expensive lookup in mkNot which is currently called for every negated argument.

mkNot seems like a simple operation, but it itself needs to use auxiliary vector for its single argument and it needs to do the lookup in the boolean term table.

Profiles suggest that sorting is typically very fast, while the lookup and copies are more expensive, so I believe this is a good tradeoff.

This could be followed by automatically sorting all commutative operators in Logic::mkFun, as proposed in #491, in which case, we could introduce (developers-only) versions of mkAnd/mkOr that would skip the simplification altogether (if we are sure the arguments are already simplified.

@blishko blishko requested a review from aehyvari May 27, 2022 20:32
@blishko
Copy link
Member Author

blishko commented May 28, 2022

I created #505 so we can actually get some concrete data on the impact of this change.

@aehyvari
Copy link
Member

aehyvari commented Jun 2, 2022

I did some benchmarking. Here are the results. 0900187f is on master and 2c7d9964 on this PR:

Big conjunction

big

Many small conjunctions

small

@blishko
Copy link
Member Author

blishko commented Jun 2, 2022

On my laptop the results are a bit different, but overall the same message. I'll dig a bit deeper because the results are not what I expected.

@aehyvari
Copy link
Member

aehyvari commented Jun 2, 2022

Sounds good! These are from mantella. I didn't try to interpret the results, I was a bit in a hurry for leaving home...

@blishko
Copy link
Member Author

blishko commented Jun 2, 2022

Actually, the results are quite different on my laptop :D
And it seems there is also a big difference depending on if std::sort of minisat sort is used. std::sort seem to be better for many arguments, especially if they are already sorted. Minisat sort is better on the conjunctions of two arguments.

Copy link
Member

@aehyvari aehyvari left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here are some tiny comments.


namespace {
struct LessThanPTRefIgnoreNot {
Logic & logic;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be const

@@ -430,89 +442,53 @@ Logic::mkIte(vec<PTRef>&& args)
PTRef Logic::mkAnd(vec<PTRef>&& args) {
if (args.size() == 0) { return getTerm_true(); }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could remove this special case. I'm not sure if it's worth it? What do you think, @blishko ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for Logic::mkOr of course.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, it is extremely rare case and it is handled later correctly anyway.
It might help the code optimization if we remove this branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants