File indexing completed on 2024-10-03 05:27:00
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include <memory>
0021 #include <atomic>
0022 #include <chrono>
0023 #include "oneapi/tbb/task_group.h"
0024 #include "oneapi/tbb/task_arena.h"
0025
0026
0027 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0028
0029 #include "FWCore/Framework/interface/MakerMacros.h"
0030
0031 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0032
0033 #include "FWCore/Utilities/interface/Exception.h"
0034
0035
0036
0037
0038
0039 class TestTBBTasksAnalyzer : public edm::one::EDAnalyzer<> {
0040 public:
0041 explicit TestTBBTasksAnalyzer(const edm::ParameterSet&);
0042 ~TestTBBTasksAnalyzer() override;
0043
0044 virtual void analyze(const edm::Event&, const edm::EventSetup&) override;
0045
0046 private:
0047 virtual void endJob() override;
0048 unsigned int startTasks(unsigned int iNTasks, unsigned int iSleepTime) const;
0049 unsigned int m_nTasksToRun;
0050 unsigned int m_expectedNumberOfSimultaneousTasks;
0051 unsigned int m_maxCountedTasks;
0052 unsigned int m_usecondsToSleep;
0053
0054 };
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 TestTBBTasksAnalyzer::TestTBBTasksAnalyzer(const edm::ParameterSet& iConfig)
0068 : m_nTasksToRun(iConfig.getUntrackedParameter<unsigned int>("numTasksToRun")),
0069 m_expectedNumberOfSimultaneousTasks(iConfig.getUntrackedParameter<unsigned int>("nExpectedThreads")),
0070 m_maxCountedTasks(0),
0071 m_usecondsToSleep(iConfig.getUntrackedParameter<unsigned int>("usecondsToSleep", 100000)) {
0072
0073 }
0074
0075 TestTBBTasksAnalyzer::~TestTBBTasksAnalyzer() {
0076
0077
0078 }
0079
0080
0081
0082
0083
0084
0085 void TestTBBTasksAnalyzer::analyze(const edm::Event&, const edm::EventSetup& iSetup) {
0086 unsigned int max = startTasks(m_nTasksToRun, m_usecondsToSleep);
0087
0088 if (max > m_maxCountedTasks) {
0089 m_maxCountedTasks = max;
0090 }
0091 }
0092
0093 unsigned int TestTBBTasksAnalyzer::startTasks(unsigned int iNTasks, unsigned int iSleepTime) const {
0094 std::atomic<unsigned int> count{0};
0095 std::atomic<unsigned int> maxCount{0};
0096 oneapi::tbb::task_group grp;
0097
0098 for (unsigned int i = 0; i < iNTasks; ++i) {
0099 grp.run([&]() {
0100 unsigned int c = ++count;
0101 while (true) {
0102 unsigned int mc = maxCount.load();
0103 if (c > mc) {
0104 if (maxCount.compare_exchange_strong(mc, c)) {
0105 break;
0106 }
0107 } else {
0108 break;
0109 }
0110 }
0111 std::this_thread::sleep_for(std::chrono::microseconds(m_usecondsToSleep));
0112 --(count);
0113 });
0114 }
0115 grp.wait();
0116 return maxCount.load();
0117 }
0118
0119 void TestTBBTasksAnalyzer::endJob() {
0120 if (((m_expectedNumberOfSimultaneousTasks - 1) > m_maxCountedTasks) ||
0121 (m_maxCountedTasks > m_expectedNumberOfSimultaneousTasks)) {
0122 throw cms::Exception("WrongNumberOfTasks")
0123 << "expected " << m_expectedNumberOfSimultaneousTasks << " but instead saw " << m_maxCountedTasks << "\n";
0124 }
0125 }
0126
0127 DEFINE_FWK_MODULE(TestTBBTasksAnalyzer);