All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
loops.h
Go to the documentation of this file.
1//
2// Copyright 2016 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_BASE_WORK_LOOPS_H
8#define PXR_BASE_WORK_LOOPS_H
9
11#include "pxr/pxr.h"
13#include "pxr/base/work/api.h"
14
15#include <tbb/blocked_range.h>
16#include <tbb/parallel_for.h>
17#include <tbb/parallel_for_each.h>
18#include <tbb/task_group.h>
19
20PXR_NAMESPACE_OPEN_SCOPE
21
34template<typename Fn>
35void
36WorkSerialForN(size_t n, Fn &&fn)
37{
38 std::forward<Fn>(fn)(0, n);
39}
40
56template <typename Fn>
57void
58WorkParallelForN(size_t n, Fn &&callback, size_t grainSize)
59{
60 if (n == 0)
61 return;
62
63 // Don't bother with parallel_for, if concurrency is limited to 1.
64 if (WorkHasConcurrency()) {
65
66 class Work_ParallelForN_TBB
67 {
68 public:
69 Work_ParallelForN_TBB(Fn &fn) : _fn(fn) { }
70
71 void operator()(const tbb::blocked_range<size_t> &r) const {
72 // Note that we std::forward _fn using Fn in order get the
73 // right operator().
74 // We maintain the right type in this way:
75 // If Fn is T&, then reference collapsing gives us T& for _fn
76 // If Fn is T, then std::forward correctly gives us T&& for _fn
77 std::forward<Fn>(_fn)(r.begin(), r.end());
78 }
79
80 private:
81 Fn &_fn;
82 };
83
84 // In most cases we do not want to inherit cancellation state from the
85 // parent context, so we create an isolated task group context.
86 tbb::task_group_context ctx(tbb::task_group_context::isolated);
87 tbb::parallel_for(tbb::blocked_range<size_t>(0,n,grainSize),
88 Work_ParallelForN_TBB(callback),
89 ctx);
90
91 } else {
92
93 // If concurrency is limited to 1, execute serially.
94 WorkSerialForN(n, std::forward<Fn>(callback));
95
96 }
97}
98
110template <typename Fn>
111void
112WorkParallelForN(size_t n, Fn &&callback)
113{
114 WorkParallelForN(n, std::forward<Fn>(callback), 1);
115}
116
130template <typename InputIterator, typename Fn>
131inline void
133 InputIterator first, InputIterator last, Fn &&fn)
134{
135 tbb::task_group_context ctx(tbb::task_group_context::isolated);
136 tbb::parallel_for_each(first, last, std::forward<Fn>(fn), ctx);
137}
138
139PXR_NAMESPACE_CLOSE_SCOPE
140
141#endif // PXR_BASE_WORK_LOOPS_H
void WorkParallelForEach(InputIterator first, InputIterator last, Fn &&fn)
WorkParallelForEach(Iterator first, Iterator last, CallbackType callback)
Definition: loops.h:132
void WorkParallelForN(size_t n, Fn &&callback, size_t grainSize)
WorkParallelForN(size_t n, CallbackType callback, size_t grainSize = 1)
Definition: loops.h:58
void WorkSerialForN(size_t n, Fn &&fn)
WorkSerialForN(size_t n, CallbackType callback)
Definition: loops.h:36
WORK_API bool WorkHasConcurrency()
Return true if WorkGetPhysicalConcurrencyLimit() returns a number greater than 1 and PXR_WORK_THREAD_...