OpenVDB: nanovdb/util/Invoke.h Source File

OpenVDB 10.1.0

Loading...
Searching...
No Matches
Invoke.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: MPL-2.0
3
4/*!
5 \file Invoke.h
6
7 \author Ken Museth
8
9 \date August 24, 2020
10
11 \brief A unified wrapper for tbb::parallel_invoke and a naive std::thread analog
12
13 @code
14 template<typename Func0, typename Func1, ..., typename FuncN>
15 int invoke(const Func0& f0, const Func1& f1, ..., const FuncN& fN);
16 @endcode
17*/
18
19#ifndef NANOVDB_INVOKE_H_HAS_BEEN_INCLUDED
20#define NANOVDB_INVOKE_H_HAS_BEEN_INCLUDED
21
22#include "../NanoVDB.h"// for nanovdb::CoordBBox
23
24#ifdef NANOVDB_USE_TBB
25#include <tbb/parallel_invoke.h>
26#endif
27
28#include <thread>
29#include <mutex>
30#include <vector>
31
32namespace nanovdb {
33
34namespace {
35#ifndef NANOVDB_USE_TBB
36// Base case
37template<typename Func>
38void parallel_invoke(std::vector<std::thread> &threadPool, const Func &taskFunc) {
39 threadPool.emplace_back(taskFunc);
40}
41
42// Iterative call
43template<typename Func, typename... Rest>
44void parallel_invoke(std::vector<std::thread> &threadPool, const Func &taskFunc1, Rest... taskFuncN) {
45 threadPool.emplace_back(taskFunc1);
46 parallel_invoke(threadPool, taskFuncN...);
47}
48
49// Base case
50template<typename Func>
51void serial_invoke(const Func &taskFunc) {taskFunc();}
52
53// Iterative call
54template<typename Func, typename... Rest>
55void serial_invoke(const Func &taskFunc1, Rest... taskFuncN) {
56 taskFunc1();
57 serial_invoke(taskFuncN...);
58}
59#endif
60}// unnamed namespace
61
62/// @return 1 for serial, 2 for tbb multi-threading, and 3 for std multi-threading
63template<typename Func, typename... Rest>
64 int invoke(const Func &taskFunc1, Rest... taskFuncN) {
65#ifdef NANOVDB_USE_TBB
66 tbb::parallel_invoke(taskFunc1, taskFuncN...);
67 return 2;
68#else
69 const auto threadCount = std::thread::hardware_concurrency()>>1;
70 if (1 + sizeof...(Rest) <= threadCount) {
71 std::vector<std::thread> threadPool;
72 threadPool.emplace_back(taskFunc1);
73 parallel_invoke(threadPool, taskFuncN...);
74 for (auto &t : threadPool) t.join();
75 return 3;// std multi-threading
76 } else {
77 taskFunc1();
78 serial_invoke(taskFuncN...);
79 return 1;// serial
80 }
81#endif
82 return -1;// should never happen
83}
84
85}// namespace nanovdb
86
87#endif // NANOVDB_INVOKE_H_HAS_BEEN_INCLUDED
nanovdb::DenseGridHandle
Definition DenseGrid.h:402
nanovdb
Definition NanoVDB.h:208
nanovdb::invoke
int invoke(const Func &taskFunc1, Rest... taskFuncN)
Definition Invoke.h:64