File indexing completed on 2025-01-18 09:11:47
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <optional>
0012
0013 #include <tbb/parallel_for.h>
0014 #include <tbb/queuing_mutex.h>
0015 #include <tbb/task_arena.h>
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 namespace ActsExamples::tbbWrap {
0028
0029
0030
0031
0032
0033 static bool enableTBB(int nthreads = -99) {
0034 static bool setting = false;
0035 if (nthreads != -99) {
0036 bool newSetting = (nthreads != 1);
0037 if (!setting && newSetting) {
0038 setting = newSetting;
0039 }
0040 }
0041 return setting;
0042 }
0043
0044
0045
0046
0047
0048 class task_arena {
0049 std::optional<tbb::task_arena> tbb;
0050
0051 public:
0052 task_arena(int nthreads = tbb::task_arena::automatic, unsigned res = 1) {
0053 if (enableTBB(nthreads)) {
0054 tbb.emplace(nthreads, res);
0055 }
0056 }
0057
0058 template <typename F>
0059 void execute(const F& f) {
0060 if (tbb) {
0061 tbb->execute(f);
0062 } else {
0063 f();
0064 }
0065 }
0066 };
0067
0068
0069 class parallel_for {
0070 public:
0071 template <typename R, typename F>
0072 parallel_for(const R& r, const F& f) {
0073 if (enableTBB()) {
0074 tbb::parallel_for(r, f);
0075 } else {
0076 for (auto i = r.begin(); i != r.end(); ++i) {
0077 f(R(i, i + 1));
0078 }
0079 }
0080 }
0081 };
0082
0083
0084 class queuing_mutex {
0085 std::optional<tbb::queuing_mutex> tbb;
0086
0087 public:
0088 queuing_mutex() {
0089 if (enableTBB()) {
0090 tbb.emplace();
0091 }
0092 }
0093
0094 class scoped_lock {
0095 std::optional<tbb::queuing_mutex::scoped_lock> tbb;
0096
0097 public:
0098 scoped_lock() {
0099 if (enableTBB()) {
0100 tbb.emplace();
0101 }
0102 }
0103
0104 explicit scoped_lock(queuing_mutex& m) {
0105 if (enableTBB()) {
0106 tbb.emplace(*m.tbb);
0107 }
0108 }
0109 };
0110 };
0111
0112 }