// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include #include LOG_SETUP("atomic_bench"); #include #include #include #include #include class Test : public vespalib::TestApp { public: template void testInc(size_t threads, size_t loops); int Main(); }; template class Changer : public FastOS_Runnable { protected: volatile T * const _idata; const int _times; public: Changer(int times, T *data) : _idata(data), _times(times) {} }; template class Incrementer : public Changer { public: Incrementer(int times, T *data) : Changer(times, data) {} void Run(FastOS_ThreadInterface *, void *) { using vespalib::Atomic; for (int i = 0; i < this->_times; ++i) { Atomic::postInc(this->_idata); } } }; template class IncrementerByCmpSwap : public Changer { public: IncrementerByCmpSwap(int times, T *data) : Changer(times, data) {} void Run(FastOS_ThreadInterface *, void *) { using vespalib::Atomic; T oldVal(0); for (int i = 0; i < this->_times; ++i) { do { oldVal = *this->_idata; } while ( ! Atomic::cmpSwap(this->_idata, oldVal+1, oldVal)); } } }; int Test::Main() { TEST_INIT("atomic_bench"); size_t concurrency(1); size_t numRuns(10000000ul); size_t benchType(0); if (_argc > 1) { benchType = strtoul(_argv[1], NULL, 0); if (_argc > 2) { numRuns = strtoul(_argv[2], NULL, 0); if (_argc > 3) { concurrency = strtoul(_argv[3], NULL, 0); } } } LOG(info, "Running test number %ld with %ld loops and concurrency of %ld", benchType, numRuns, concurrency); if (benchType == 1) { testInc, uint64_t>(concurrency, numRuns); } else { testInc, uint64_t>(concurrency, numRuns); } TEST_FLUSH(); TEST_DONE(); } template void Test::testInc(size_t numThreads, size_t loopCount) { std::vector> threads3(numThreads); T uintcounter = 0; FastOS_ThreadPool tpool3(65000, numThreads); for (size_t i = 0; i < numThreads; i++) { threads3[i] = std::make_unique(loopCount, &uintcounter); tpool3.NewThread(threads3[i].get()); } tpool3.Close(); EXPECT_TRUE(uintcounter == numThreads * loopCount); TEST_FLUSH(); } TEST_APPHOOK(Test)