-
Notifications
You must be signed in to change notification settings - Fork 94
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
Optimization (std::map, etc) #483
Comments
Another 150ms saved here: diff --git a/src/manifold/src/boolean_result.cpp b/src/manifold/src/boolean_result.cpp
index 8d54ed8..cd717a8 100644
--- a/src/manifold/src/boolean_result.cpp
+++ b/src/manifold/src/boolean_result.cpp
@@ -481,7 +481,7 @@ void CreateProperties(Manifold::Impl &outR, const VecDH<TriRef> &refPQ,
inP.halfedge_.cptrD(), inQ.halfedge_.cptrD(),
outR.halfedge_.cptrD(), outR.precision_}));
- std::map<std::tuple<int, int, int, int>, int> propIdx;
+ phmap::flat_hash_map<glm::ivec4, int> propIdx;
int idx = 0;
for (int tri = 0; tri < numTri; ++tri) {
@@ -501,14 +501,14 @@ void CreateProperties(Manifold::Impl &outR, const VecDH<TriRef> &refPQ,
const int vert = outR.halfedge_[3 * tri + i].startVert;
const glm::vec3 uvw = bary[3 * tri + i];
- auto key = std::make_tuple(PQ, -1, -1, -1);
+ glm::ivec4 key(PQ, -1, -1, -1);
if (oldNumProp > 0) {
- std::get<1>(key) = vert;
+ key[1] = vert;
int edge = -1;
for (const int j : {0, 1, 2}) {
if (uvw[j] == 1) {
// On a retained vert, the propVert must also match
- std::get<2>(key) = triProp[j];
+ key[2] = triProp[j];
edge = -1;
break;
}
@@ -518,18 +518,15 @@ void CreateProperties(Manifold::Impl &outR, const VecDH<TriRef> &refPQ,
// On an edge, both propVerts must match
const int p0 = triProp[Next3(edge)];
const int p1 = triProp[Prev3(edge)];
- std::get<2>(key) = glm::min(p0, p1);
- std::get<3>(key) = glm::max(p0, p1);
+ key[2] = glm::min(p0, p1);
+ key[3] = glm::max(p0, p1);
}
}
- const auto it = propIdx.find(key);
- if (it != propIdx.end()) {
- outR.meshRelation_.triProperties[tri][i] = it->second;
- continue;
- }
- outR.meshRelation_.triProperties[tri][i] = idx;
- propIdx.insert({key, idx++});
+ const auto it = propIdx.try_emplace(key, idx);
+ outR.meshRelation_.triProperties[tri][i] = it.first->second;
+ if (!it.second) continue;
+ idx++;
for (int p = 0; p < numProp; ++p) {
if (p < oldNumProp) {
|
Excellent - again, can you put this in the form of a PR? Would love to review and merge. |
Also, we have our own simple little parallel hash table - curious how it stacks up against the others? Would be nice to be consistent. |
It seems that there are also other uses of std::map, wondering if replacing those can make a different as well |
Other uses of I checked the My test branch: stephomi@0b5161d Edit: I'm testing against the TBB backend (OMP through thrust backend has broken performance on my machine) |
I'm open to this if we can avoid pulling in a boost dependency. |
Just be careful that deterministic operation is preserved when you disorder maps, etc. |
It should be fine as we don't perform anything that is order dependent here. For deterministic behavior however, I think our output is not deterministic when multithreading is enabled, I forgot if we have deterministic output when we execute everything in a single thread. |
* remove extra prefetch this is in the hot path and causes performance issues * implemented optimization proposed by @stephomi in elalish#483 * formatting * fix cuda build * combine the loop
std::map
should only be used if ordering needs to be preserved.Case study: subtract a 150k verts mesh on a 400k verts one.
The entire getMeshGL() took 770ms, by replacing 2 minor thing I got it down to <600ms.
By testing this section (175ms):
manifold/src/manifold/src/manifold.cpp
Line 287 in 96c57c0
try_emplace
instead offind/insert
to perform only 1 map queryThe text was updated successfully, but these errors were encountered: