OpenVDB: nanovdb/util/Invoke.h Source File

OpenVDB 12.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: Apache-2.0
3
4/*!
5 \file nanovdb/util/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_UTIL_INVOKE_H_HAS_BEEN_INCLUDED
20#define NANOVDB_UTIL_INVOKE_H_HAS_BEEN_INCLUDED
21
22#include <nanovdb/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 util {
35
36namespace {
37#ifndef NANOVDB_USE_TBB
38// Base case
39template<typename Func>
40void parallel_invoke(std::vector<std::thread> &threadPool, const Func &taskFunc) {
41 threadPool.emplace_back(taskFunc);
42}
43
44// Iterative call
45template<typename Func, typename... Rest>
46void parallel_invoke(std::vector<std::thread> &threadPool, const Func &taskFunc1, Rest... taskFuncN) {
47 threadPool.emplace_back(taskFunc1);
48 parallel_invoke(threadPool, taskFuncN...);
49}
50
51// Base case
52template<typename Func>
53void serial_invoke(const Func &taskFunc) {taskFunc();}
54
55// Iterative call
56template<typename Func, typename... Rest>
57void serial_invoke(const Func &taskFunc1, Rest... taskFuncN) {
58 taskFunc1();
59 serial_invoke(taskFuncN...);
60}
61#endif
62}// unnamed namespace
63
64/// @return 1 for serial, 2 for tbb multi-threading, and 3 for std multi-threading
65template<typename Func, typename... Rest>
66 int invoke(const Func &taskFunc1, Rest... taskFuncN) {
67#ifdef NANOVDB_USE_TBB
68 tbb::parallel_invoke(taskFunc1, taskFuncN...);
69 return 2;
70#else
71 const auto threadCount = std::thread::hardware_concurrency()>>1;
72 if (1 + sizeof...(Rest) <= threadCount) {
73 std::vector<std::thread> threadPool;
74 threadPool.emplace_back(taskFunc1);
75 parallel_invoke(threadPool, taskFuncN...);
76 for (auto &t : threadPool) t.join();
77 return 3;// std multi-threading
78 } else {
79 taskFunc1();
80 serial_invoke(taskFuncN...);
81 return 1;// serial
82 }
83#endif
84 return -1;// should never happen
85}
86
87}// namespace util
88
89template<typename Func, typename... Rest>
90[[deprecated("Use nanovdb::util::invoke instead")]]
91 int invoke(const Func &taskFunc1, Rest... taskFuncN) {
92 return util::invoke<Func, Rest...>(taskFunc1, taskFuncN...);
93}
94
95}// namespace nanovdb
96
97#endif // NANOVDB_UTIL_INVOKE_H_HAS_BEEN_INCLUDED
NanoVDB.h
Implements a light-weight self-contained VDB data-structure in a single file! In other words,...
nanovdb::util
Definition ForEach.h:29
nanovdb::util::invoke
int invoke(const Func &taskFunc1, Rest... taskFuncN)
Definition Invoke.h:66
nanovdb
Definition GridHandle.h:27
nanovdb::invoke
int invoke(const Func &taskFunc1, Rest... taskFuncN)
Definition Invoke.h:91