barrier.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // Copyright 2009-2021 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #include "intrinsics.h"
  5. #include "sysinfo.h"
  6. #include "atomic.h"
  7. namespace embree
  8. {
  9. /*! system barrier using operating system */
  10. class BarrierSys
  11. {
  12. public:
  13. /*! construction / destruction */
  14. BarrierSys (size_t N = 0);
  15. ~BarrierSys ();
  16. private:
  17. /*! class in non-copyable */
  18. BarrierSys (const BarrierSys& other) DELETED; // do not implement
  19. BarrierSys& operator= (const BarrierSys& other) DELETED; // do not implement
  20. public:
  21. /*! initializes the barrier with some number of threads */
  22. void init(size_t count);
  23. /*! lets calling thread wait in barrier */
  24. void wait();
  25. private:
  26. void* opaque;
  27. };
  28. /*! fast active barrier using atomic counter */
  29. struct BarrierActive
  30. {
  31. public:
  32. BarrierActive ()
  33. : cntr(0) {}
  34. void reset() {
  35. cntr.store(0);
  36. }
  37. void wait (size_t numThreads)
  38. {
  39. cntr++;
  40. while (cntr.load() != numThreads)
  41. pause_cpu();
  42. }
  43. private:
  44. std::atomic<size_t> cntr;
  45. };
  46. /*! fast active barrier that does not require initialization to some number of threads */
  47. struct BarrierActiveAutoReset
  48. {
  49. public:
  50. BarrierActiveAutoReset ()
  51. : cntr0(0), cntr1(0) {}
  52. void wait (size_t threadCount)
  53. {
  54. cntr0.fetch_add(1);
  55. while (cntr0 != threadCount) pause_cpu();
  56. cntr1.fetch_add(1);
  57. while (cntr1 != threadCount) pause_cpu();
  58. cntr0.fetch_add(-1);
  59. while (cntr0 != 0) pause_cpu();
  60. cntr1.fetch_add(-1);
  61. while (cntr1 != 0) pause_cpu();
  62. }
  63. private:
  64. std::atomic<size_t> cntr0;
  65. std::atomic<size_t> cntr1;
  66. };
  67. class LinearBarrierActive
  68. {
  69. public:
  70. /*! construction and destruction */
  71. LinearBarrierActive (size_t threadCount = 0);
  72. ~LinearBarrierActive();
  73. private:
  74. /*! class in non-copyable */
  75. LinearBarrierActive (const LinearBarrierActive& other) DELETED; // do not implement
  76. LinearBarrierActive& operator= (const LinearBarrierActive& other) DELETED; // do not implement
  77. public:
  78. /*! initializes the barrier with some number of threads */
  79. void init(size_t threadCount);
  80. /*! thread with threadIndex waits in the barrier */
  81. void wait (const size_t threadIndex);
  82. private:
  83. volatile unsigned char* count0;
  84. volatile unsigned char* count1;
  85. volatile unsigned int mode;
  86. volatile unsigned int flag0;
  87. volatile unsigned int flag1;
  88. volatile size_t threadCount;
  89. };
  90. }