Skip to content

Performance improvement and cleanup of local bitvector analysis #6528

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 15, 2021

Conversation

tautschnig
Copy link
Collaborator

Please review commit-by-commit. The commit messages include performance evaluation data.

  • Each commit message has a non-empty body, explaining why the change was made.
  • n/a Methods or procedures I have added are documented, following the guidelines provided in CODING_STANDARD.md.
  • n/a The feature or user visible behaviour I have added or modified has been documented in the User Guide in doc/cprover-manual/
  • Regression or unit tests are included, or existing tests cover the modified code (in this case I have detailed which ones those are in the commit message).
  • My commit message includes data points confirming performance improvements (if claimed).
  • My PR is restricted to a single feature or bugfix.
  • n/a White-space or formatting changes outside the feature-related changed lines are in commits of their own.

@kroening
Copy link
Member

Commit message: "enqueuing successor nodes" -> "dequeuing successor nodes"

By using a set instead of a stack as work queue we reduce the number of
visits to each node in two ways:
1) The work queue will not contain duplicate nodes.
2) When dequeuing successor nodes, back edges will be given preference
over forward ones. Once the later (in program order) node is visited,
more information is already merged into the abstract state.

On a goto function with 160822 instruction, this reduces processing time
(just the local bitvector analysis) from 1700 seconds down to 72
seconds. The number of invocations of `local_bitvector_analysist::merge`
previously was 32815499 (204 times the number of nodes), and is now
997083 (6 times the number of nodes).
This avoids a jump. On a goto function of 160822 instructions, the total
time required by local bitvector analysis decreases from 72 seconds to
65 seconds (averaged over three runs, the difference between the slowest
and longest run is below 0.2 seconds).
The correct type is std::size_t in all cases. Use `auto` where the type
can be inferred, and the typedef'd name where it's `local_cfgt`'s
business to choose the type.
@tautschnig
Copy link
Collaborator Author

Commit message: "enqueuing successor nodes" -> "dequeuing successor nodes"

Err, of course, thank you!

@codecov
Copy link

codecov bot commented Dec 15, 2021

Codecov Report

Merging #6528 (8834dc5) into develop (5f33908) will increase coverage by 0.00%.
The diff coverage is 96.42%.

Impacted file tree graph

@@           Coverage Diff            @@
##           develop    #6528   +/-   ##
========================================
  Coverage    75.98%   75.98%           
========================================
  Files         1578     1578           
  Lines       180910   180919    +9     
========================================
+ Hits        137467   137476    +9     
  Misses       43443    43443           
Impacted Files Coverage Δ
src/analyses/local_bitvector_analysis.h 90.19% <ø> (ø)
src/analyses/local_bitvector_analysis.cpp 73.98% <88.88%> (-0.15%) ⬇️
src/goto-instrument/contracts/contracts.cpp 95.11% <100.00%> (+0.07%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update eeddb3f...8834dc5. Read the comment docs.

Copy link
Collaborator

@martin-cs martin-cs left a comment

Choose a reason for hiding this comment

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

20x speed-up due to a change in data-structure! I love it! Classic computer science. Would it be possible to have another PR that s/stack/set/ in local_may_aliast too?

@@ -242,8 +242,8 @@ void local_bitvector_analysist::build()
if(cfg.nodes.empty())
return;

work_queuet work_queue;
Copy link
Collaborator

Choose a reason for hiding this comment

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

This one has a friend who would also like to become a set:

typedef std::stack<local_cfgt::node_nrt> work_queuet;

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good call, I'll do so in a follow-up PR.

@tautschnig tautschnig merged commit 73fbad9 into diffblue:develop Dec 15, 2021
@tautschnig tautschnig deleted the bitvector-analysis branch December 15, 2021 15:11
if(a[i].merge(b[i]))
result=true;
}
result |= a[i].merge(b[i]);
Copy link
Member

Choose a reason for hiding this comment

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

I would add a comment that the bitwise or is used instead of the logical or to prevent the short-circuit semantics.

work_queuet work_queue;
work_queue.push(0);
std::set<local_cfgt::node_nrt> work_queue;
work_queue.insert(0);

Copy link
Member

Choose a reason for hiding this comment

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

Queues are usually ordered (especially in the UK). Is the set really helping performance, and if so, I'd rename it to "work_set".

Copy link
Collaborator

@remi-delmas-3000 remi-delmas-3000 left a comment

Choose a reason for hiding this comment

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

Can this result in a different fixed point being reached ? What are the implications for the precision of the analysis ? Are there any iteration strategies that can result in more precise results ? In any acceptable perf tradeoff that favors precision might more useful for users of this class.

@martin-cs
Copy link
Collaborator

martin-cs commented Dec 15, 2021 via email

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.

4 participants