Skip to content
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

remove deterministic flag #1033

Merged
merged 1 commit into from
Nov 14, 2024
Merged

remove deterministic flag #1033

merged 1 commit into from
Nov 14, 2024

Conversation

elalish
Copy link
Owner

@elalish elalish commented Nov 9, 2024

I want to remove the deterministic flag from our execution parameters - it leaves untested code paths that concern me. The question is what is more important: determinism or speed? I'm not quite ready to merge this as is because forcing everything to be deterministic all the time is making our tests run about 20% slower (at least on my M1 macbook pro). WDYT @pca006132?

@elalish elalish self-assigned this Nov 9, 2024
@pca006132
Copy link
Collaborator

I see. I think the AddNewEdgeVerts is likely the reason for the slowdown, due to the lack of parallelization previously. We can keep that one and see if it makes the results non-deterministic. There should be ways to speed it up without sacrificing determinism, but this is probably something for later.

For the other change, can you check if removing it will cause major slowdown?

@pca006132
Copy link
Collaborator

Some additional context: Due to things like floating point, and changes to mesh simplification, enabling the deterministic version will not give you the same result across different versions or with different machines. I think this also makes deterministic result less important for our use case because we can't have that in general, and not sure if users demanding deterministic result are happy with only this same version guarantee (if it holds at all... we never actually tested it anyway).

I think we can just remove the flag and keep the things that may cause nondeterminism, and try to deal with them later when someone complains.

@pca006132
Copy link
Collaborator

Another reason: Floating point operations are not really associative, and making this deterministic will require a lot more changes. The topology may be deterministic previously with the deterministic flag on, but things like normal and positions are probably not. If users want deterministic results, they should probably run with parallelization disabled (either compile with that or limit to 1 CPU core).

Copy link
Owner Author

@elalish elalish left a comment

Choose a reason for hiding this comment

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

Okay, reversing course and taking the determinism == false branches all the time now. I agree it's likely impossible to get deterministic results across architectures. I'd rather users don't start assuming determinism, particularly across our point releases.

@@ -253,7 +253,7 @@ void AddNewEdgeVerts(
#if (MANIFOLD_PAR == 1) && __has_include(<tbb/tbb.h>)
// parallelize operations, requires concurrent_map so we can only enable this
// with tbb
if (!ManifoldParams().deterministic && p1q2.size() > kParallelThreshold) {
if (p1q2.size() > kParallelThreshold) {
Copy link
Owner Author

Choose a reason for hiding this comment

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

@pca006132 Actually, switching this to serial had the smallest performance impact of anything, but for now I'm going with the determinism == false path for everything.

SharedImpl r;
queue.try_pop(r);
return *std::get_if<std::shared_ptr<Manifold::Impl>>(&r);
tbb::task_group group;
Copy link
Owner Author

Choose a reason for hiding this comment

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

This one had a noticeable perf impact when removed, but not huge.

? ExecutionPolicy::Par
: ExecutionPolicy::Seq,
impl->children_.begin(), impl->children_.end(), [](auto &child) {
for_each(ExecutionPolicy::Par, impl->children_.begin(),
Copy link
Owner Author

Choose a reason for hiding this comment

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

Changing this to Seq caused about 75% of the performance regression I was seeing. Even just the impl->children_.size() > 1 check was causing noticeable perf regression.

@pca006132
Copy link
Collaborator

maybe we can document this in https://github.com/elalish/manifold/wiki/Performance-Considerations

@elalish elalish merged commit a41a361 into master Nov 14, 2024
19 checks passed
@elalish elalish deleted the determinism branch November 14, 2024 05:15
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