mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-03 01:00:37 +08:00
Optimization of triangle mesh slicing: scalable_allocator and hashing
of shared mutexes.
This commit is contained in:
parent
0836b06c73
commit
31a5daa5e4
@ -15,6 +15,9 @@
|
|||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
|
|
||||||
#include <tbb/parallel_for.h>
|
#include <tbb/parallel_for.h>
|
||||||
|
#include <tbb/scalable_allocator.h>
|
||||||
|
|
||||||
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
// #define EXPENSIVE_DEBUG_CHECKS
|
// #define EXPENSIVE_DEBUG_CHECKS
|
||||||
@ -139,7 +142,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
using IntersectionLines = std::vector<IntersectionLine>;
|
using IntersectionLines = std::vector<IntersectionLine, tbb::scalable_allocator<IntersectionLine>>;
|
||||||
|
|
||||||
enum class FacetSliceType {
|
enum class FacetSliceType {
|
||||||
NoSlice = 0,
|
NoSlice = 0,
|
||||||
@ -351,6 +354,21 @@ inline FacetSliceType slice_facet(
|
|||||||
return FacetSliceType::NoSlice;
|
return FacetSliceType::NoSlice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class LinesMutexes {
|
||||||
|
public:
|
||||||
|
std::mutex& operator()(size_t slice_id) {
|
||||||
|
ankerl::unordered_dense::hash<size_t> hash;
|
||||||
|
return m_mutexes[hash(slice_id) % m_mutexes.size()].mutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct CacheLineAlignedMutex
|
||||||
|
{
|
||||||
|
alignas(std::hardware_destructive_interference_size) std::mutex mutex;
|
||||||
|
};
|
||||||
|
std::array<CacheLineAlignedMutex, 64> m_mutexes;
|
||||||
|
};
|
||||||
|
|
||||||
template<typename TransformVertex>
|
template<typename TransformVertex>
|
||||||
void slice_facet_at_zs(
|
void slice_facet_at_zs(
|
||||||
// Scaled or unscaled vertices. transform_vertex_fn may scale zs.
|
// Scaled or unscaled vertices. transform_vertex_fn may scale zs.
|
||||||
@ -361,7 +379,7 @@ void slice_facet_at_zs(
|
|||||||
// Scaled or unscaled zs. If vertices have their zs scaled or transform_vertex_fn scales them, then zs have to be scaled as well.
|
// Scaled or unscaled zs. If vertices have their zs scaled or transform_vertex_fn scales them, then zs have to be scaled as well.
|
||||||
const std::vector<float> &zs,
|
const std::vector<float> &zs,
|
||||||
std::vector<IntersectionLines> &lines,
|
std::vector<IntersectionLines> &lines,
|
||||||
std::array<std::mutex, 64> &lines_mutex)
|
LinesMutexes &lines_mutex)
|
||||||
{
|
{
|
||||||
stl_vertex vertices[3] { transform_vertex_fn(mesh_vertices[indices(0)]), transform_vertex_fn(mesh_vertices[indices(1)]), transform_vertex_fn(mesh_vertices[indices(2)]) };
|
stl_vertex vertices[3] { transform_vertex_fn(mesh_vertices[indices(0)]), transform_vertex_fn(mesh_vertices[indices(1)]), transform_vertex_fn(mesh_vertices[indices(2)]) };
|
||||||
|
|
||||||
@ -380,7 +398,7 @@ void slice_facet_at_zs(
|
|||||||
if (min_z != max_z && slice_facet(*it, vertices, indices, edge_ids, idx_vertex_lowest, false, il) == FacetSliceType::Slicing) {
|
if (min_z != max_z && slice_facet(*it, vertices, indices, edge_ids, idx_vertex_lowest, false, il) == FacetSliceType::Slicing) {
|
||||||
assert(il.edge_type != IntersectionLine::FacetEdgeType::Horizontal);
|
assert(il.edge_type != IntersectionLine::FacetEdgeType::Horizontal);
|
||||||
size_t slice_id = it - zs.begin();
|
size_t slice_id = it - zs.begin();
|
||||||
boost::lock_guard<std::mutex> l(lines_mutex[slice_id % lines_mutex.size()]);
|
boost::lock_guard<std::mutex> l(lines_mutex(slice_id));
|
||||||
lines[slice_id].emplace_back(il);
|
lines[slice_id].emplace_back(il);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -395,8 +413,8 @@ static inline std::vector<IntersectionLines> slice_make_lines(
|
|||||||
const std::vector<float> &zs,
|
const std::vector<float> &zs,
|
||||||
const ThrowOnCancel throw_on_cancel_fn)
|
const ThrowOnCancel throw_on_cancel_fn)
|
||||||
{
|
{
|
||||||
std::vector<IntersectionLines> lines(zs.size(), IntersectionLines());
|
std::vector<IntersectionLines> lines(zs.size(), IntersectionLines{});
|
||||||
std::array<std::mutex, 64> lines_mutex;
|
LinesMutexes lines_mutex;
|
||||||
tbb::parallel_for(
|
tbb::parallel_for(
|
||||||
tbb::blocked_range<int>(0, int(indices.size())),
|
tbb::blocked_range<int>(0, int(indices.size())),
|
||||||
[&vertices, &transform_vertex_fn, &indices, &face_edge_ids, &zs, &lines, &lines_mutex, throw_on_cancel_fn](const tbb::blocked_range<int> &range) {
|
[&vertices, &transform_vertex_fn, &indices, &face_edge_ids, &zs, &lines, &lines_mutex, throw_on_cancel_fn](const tbb::blocked_range<int> &range) {
|
||||||
@ -475,7 +493,7 @@ void slice_facet_with_slabs(
|
|||||||
const int num_edges,
|
const int num_edges,
|
||||||
const std::vector<float> &zs,
|
const std::vector<float> &zs,
|
||||||
SlabLines &lines,
|
SlabLines &lines,
|
||||||
std::array<std::mutex, 64> &lines_mutex)
|
LinesMutexes &lines_mutex)
|
||||||
{
|
{
|
||||||
const stl_triangle_vertex_indices &indices = mesh_triangles[facet_idx];
|
const stl_triangle_vertex_indices &indices = mesh_triangles[facet_idx];
|
||||||
stl_vertex vertices[3] { mesh_vertices[indices(0)], mesh_vertices[indices(1)], mesh_vertices[indices(2)] };
|
stl_vertex vertices[3] { mesh_vertices[indices(0)], mesh_vertices[indices(1)], mesh_vertices[indices(2)] };
|
||||||
@ -494,7 +512,7 @@ void slice_facet_with_slabs(
|
|||||||
auto emit_slab_edge = [&lines, &lines_mutex](IntersectionLine il, size_t slab_id, bool reverse) {
|
auto emit_slab_edge = [&lines, &lines_mutex](IntersectionLine il, size_t slab_id, bool reverse) {
|
||||||
if (reverse)
|
if (reverse)
|
||||||
il.reverse();
|
il.reverse();
|
||||||
boost::lock_guard<std::mutex> l(lines_mutex[(slab_id + lines_mutex.size() / 2) % lines_mutex.size()]);
|
boost::lock_guard<std::mutex> l(lines_mutex(slab_id));
|
||||||
lines.between_slices[slab_id].emplace_back(il);
|
lines.between_slices[slab_id].emplace_back(il);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -530,7 +548,7 @@ void slice_facet_with_slabs(
|
|||||||
};
|
};
|
||||||
// Don't flip the FacetEdgeType::Top edge, it will be flipped when chaining.
|
// Don't flip the FacetEdgeType::Top edge, it will be flipped when chaining.
|
||||||
// if (! ProjectionFromTop) il.reverse();
|
// if (! ProjectionFromTop) il.reverse();
|
||||||
boost::lock_guard<std::mutex> l(lines_mutex[line_id % lines_mutex.size()]);
|
boost::lock_guard<std::mutex> l(lines_mutex(line_id));
|
||||||
lines.at_slice[line_id].emplace_back(il);
|
lines.at_slice[line_id].emplace_back(il);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -649,7 +667,7 @@ void slice_facet_with_slabs(
|
|||||||
if (! ProjectionFromTop)
|
if (! ProjectionFromTop)
|
||||||
il.reverse();
|
il.reverse();
|
||||||
size_t line_id = it - zs.begin();
|
size_t line_id = it - zs.begin();
|
||||||
boost::lock_guard<std::mutex> l(lines_mutex[line_id % lines_mutex.size()]);
|
boost::lock_guard<std::mutex> l(lines_mutex(line_id));
|
||||||
lines.at_slice[line_id].emplace_back(il);
|
lines.at_slice[line_id].emplace_back(il);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -804,8 +822,8 @@ inline std::pair<SlabLines, SlabLines> slice_slabs_make_lines(
|
|||||||
std::pair<SlabLines, SlabLines> out;
|
std::pair<SlabLines, SlabLines> out;
|
||||||
SlabLines &lines_top = out.first;
|
SlabLines &lines_top = out.first;
|
||||||
SlabLines &lines_bottom = out.second;
|
SlabLines &lines_bottom = out.second;
|
||||||
std::array<std::mutex, 64> lines_mutex_top;
|
LinesMutexes lines_mutex_top;
|
||||||
std::array<std::mutex, 64> lines_mutex_bottom;
|
LinesMutexes lines_mutex_bottom;
|
||||||
|
|
||||||
if (top) {
|
if (top) {
|
||||||
lines_top.at_slice.assign(zs.size(), IntersectionLines());
|
lines_top.at_slice.assign(zs.size(), IntersectionLines());
|
||||||
@ -1540,7 +1558,7 @@ static std::vector<Polygons> make_slab_loops(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Used to cut the mesh into two halves.
|
// Used to cut the mesh into two halves.
|
||||||
static ExPolygons make_expolygons_simple(std::vector<IntersectionLine> &lines)
|
static ExPolygons make_expolygons_simple(IntersectionLines &lines)
|
||||||
{
|
{
|
||||||
ExPolygons slices;
|
ExPolygons slices;
|
||||||
Polygons holes;
|
Polygons holes;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user