OpenVDB
13.0.0
Toggle main menu visibility
Loading...
Searching...
No Matches
ForEach.h
Go to the documentation of this file.
1
// Copyright Contributors to the OpenVDB Project
2
// SPDX-License-Identifier: Apache-2.0
3
4
/*!
5
\file nanovdb/util/ForEach.h
6
7
\author Ken Museth
8
9
\date August 24, 2020
10
11
\brief A unified wrapper for tbb::parallel_for and a naive std::thread fallback
12
*/
13
14
#ifndef NANOVDB_UTIL_FOREACH_H_HAS_BEEN_INCLUDED
15
#define NANOVDB_UTIL_FOREACH_H_HAS_BEEN_INCLUDED
16
17
#include <
nanovdb/util/Range.h
>
// for Range1D
18
19
#ifdef NANOVDB_USE_TBB
20
#include <tbb/parallel_for.h>
21
#else
22
#include <thread>
23
#include <mutex>
24
#include <vector>
25
#endif
26
27
namespace
nanovdb
{
28
29
namespace
util
{
30
31
/// @brief simple wrapper for tbb::parallel_for with a naive std fallback
32
///
33
/// @param range Range, CoordBBox, tbb::blocked_range, blocked_range2D, or blocked_range3D.
34
/// @param func functor with the signature [](const RangeT&){...},
35
///
36
/// @code
37
/// std::vector<int> array(100);
38
/// auto func = [&array](auto &r){for (auto i=r.begin(); i!=r.end(); ++i) array[i]=i;};
39
/// forEach(array, func);
40
/// @endcode
41
template
<
typename
RangeT,
typename
FuncT>
42
inline
void
forEach
(RangeT range,
const
FuncT &func)
43
{
44
if
(range.empty())
return
;
45
#ifdef NANOVDB_USE_TBB
46
tbb::parallel_for(range, func);
47
#else
// naive and likely slow alternative based on std::thread
48
if
(
const
size_t
threadCount = std::thread::hardware_concurrency()>>1) {
49
std::vector<RangeT> rangePool{ range };
50
while
(rangePool.size() < threadCount) {
51
const
size_t
oldSize = rangePool.size();
52
for
(
size_t
i = 0; i < oldSize && rangePool.size() < threadCount; ++i) {
53
auto
&r = rangePool[i];
54
if
(r.is_divisible()) rangePool.push_back(RangeT(r,
Split
()));
55
}
56
if
(rangePool.size() == oldSize)
break
;
// none of the ranges were divided so stop
57
}
58
std::vector<std::thread> threadPool;
59
for
(
auto
&r : rangePool) threadPool.emplace_back(func, r);
// launch threads
60
for
(
auto
&t : threadPool) t.join();
// synchronize threads
61
}
else
{
//serial
62
func(range);
63
}
64
#endif
65
}
66
67
/// @brief Simple wrapper for the function defined above
68
template
<
typename
FuncT>
69
inline
void
forEach
(
size_t
begin,
size_t
end,
size_t
grainSize,
const
FuncT& func)
70
{
71
forEach
(
Range1D
(begin, end, grainSize), func);
72
}
73
74
/// @brief Simple wrapper for the function defined above, which works with std::containers
75
template
<
template
<
typename
...>
class
ContainerT,
typename
... T,
typename
FuncT>
76
inline
void
forEach
(
const
ContainerT<T...> &c,
const
FuncT& func)
77
{
78
forEach
(
Range1D
(0, c.size(), 1), func);
79
}
80
81
/// @brief Simple wrapper for the function defined above, which works with std::containers
82
template
<
template
<
typename
...>
class
ContainerT,
typename
... T,
typename
FuncT>
83
inline
void
forEach
(
const
ContainerT<T...> &c,
size_t
grainSize,
const
FuncT& func)
84
{
85
forEach
(
Range1D
(0, c.size(), grainSize), func);
86
}
87
88
}
// namespace util
89
90
/// @brief Simple wrapper for the function defined above
91
template
<
typename
FuncT>
92
[[deprecated(
"Use nanovdb::util::forEach instead"
)]]
93
inline
void
forEach
(
size_t
begin,
size_t
end,
size_t
grainSize,
const
FuncT& func)
94
{
95
util::forEach
(
util::Range1D
(begin, end, grainSize), func);
96
}
97
98
/// @brief Simple wrapper for the function defined above, which works with std::containers
99
template
<
template
<
typename
...>
class
ContainerT,
typename
... T,
typename
FuncT>
100
[[deprecated(
"Use nanovdb::util::forEach instead"
)]]
101
inline
void
forEach
(
const
ContainerT<T...> &c,
const
FuncT& func)
102
{
103
util::forEach
(
util::Range1D
(0, c.size(), 1), func);
104
}
105
106
/// @brief Simple wrapper for the function defined above, which works with std::containers
107
template
<
template
<
typename
...>
class
ContainerT,
typename
... T,
typename
FuncT>
108
[[deprecated(
"Use nanovdb::util::forEach instead"
)]]
109
inline
void
forEach
(
const
ContainerT<T...> &c,
size_t
grainSize,
const
FuncT& func)
110
{
111
util::forEach
(
util::Range1D
(0, c.size(), grainSize), func);
112
}
113
114
}
// namespace nanovdb
115
116
#endif
// NANOVDB_UTIL_FOREACH_H_HAS_BEEN_INCLUDED
Range.h
Custom Range class that is compatible with the tbb::blocked_range classes.
nanovdb::util::Split
Definition
Range.h:28
nanovdb::util
Definition
ForEach.h:29
nanovdb::util::forEach
void forEach(RangeT range, const FuncT &func)
simple wrapper for tbb::parallel_for with a naive std fallback
Definition
ForEach.h:42
nanovdb::util::Range1D
Range< 1, size_t > Range1D
Definition
Range.h:33
nanovdb
Definition
GridHandle.h:27
nanovdb::forEach
void forEach(size_t begin, size_t end, size_t grainSize, const FuncT &func)
Simple wrapper for the function defined above.
Definition
ForEach.h:93
nanovdb
util
ForEach.h
Generated by
1.18.0