taskschedulertbb.cpp 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // ======================================================================== //
  2. // Copyright 2009-2017 Intel Corporation //
  3. // //
  4. // Licensed under the Apache License, Version 2.0 (the "License"); //
  5. // you may not use this file except in compliance with the License. //
  6. // You may obtain a copy of the License at //
  7. // //
  8. // http://www.apache.org/licenses/LICENSE-2.0 //
  9. // //
  10. // Unless required by applicable law or agreed to in writing, software //
  11. // distributed under the License is distributed on an "AS IS" BASIS, //
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
  13. // See the License for the specific language governing permissions and //
  14. // limitations under the License. //
  15. // ======================================================================== //
  16. #include "taskschedulertbb.h"
  17. namespace embree
  18. {
  19. static bool g_tbb_threads_initialized = false;
  20. static tbb::task_scheduler_init g_tbb_threads(tbb::task_scheduler_init::deferred);
  21. class TBBAffinity: public tbb::task_scheduler_observer
  22. {
  23. tbb::atomic<int> threadCount;
  24. public:
  25. TBBAffinity() {
  26. threadCount = 0;
  27. }
  28. void on_scheduler_entry( bool )
  29. {
  30. const int threadIndex = threadCount++;
  31. setAffinity(threadIndex); // do not use TaskScheduler::threadIndex() as old TBB versions to not have that function
  32. }
  33. void on_scheduler_exit( bool ) {
  34. threadCount--;
  35. }
  36. } tbb_affinity;
  37. void TaskScheduler::create(size_t numThreads, bool set_affinity, bool start_threads)
  38. {
  39. assert(numThreads);
  40. /* first terminate threads in case we configured them */
  41. if (g_tbb_threads_initialized) {
  42. g_tbb_threads.terminate();
  43. g_tbb_threads_initialized = false;
  44. }
  45. /* only set affinity if requested by the user */
  46. if (set_affinity)
  47. tbb_affinity.observe(true);
  48. /* now either keep default settings or configure number of threads */
  49. if (numThreads == std::numeric_limits<size_t>::max()) {
  50. g_tbb_threads_initialized = false;
  51. numThreads = threadCount();
  52. //numThreads = tbb::task_scheduler_init::default_num_threads();
  53. } else {
  54. g_tbb_threads_initialized = true;
  55. const int max_concurrency = threadCount();
  56. if (numThreads > max_concurrency) numThreads = max_concurrency;
  57. g_tbb_threads.initialize(int(numThreads));
  58. }
  59. /* start worker threads */
  60. if (start_threads)
  61. {
  62. BarrierSys barrier(numThreads);
  63. tbb::parallel_for(size_t(0), size_t(numThreads), size_t(1), [&] ( size_t i ) {
  64. barrier.wait();
  65. });
  66. }
  67. }
  68. void TaskScheduler::destroy()
  69. {
  70. if (g_tbb_threads_initialized) {
  71. g_tbb_threads.terminate();
  72. g_tbb_threads_initialized = false;
  73. }
  74. }
  75. }