#include "RealTime.h" #include #include #include #include #include #include #include #include #include // convert gcc to c0xx #define thread_local __thread typedef std::thread Thread; typedef std::vector ThreadGroup; typedef std::mutex Mutex; typedef std::unique_lock Guard; typedef std::condition_variable Condition; #include long long threadId() { std::stringstream ss; ss << std::this_thread::get_id(); long long id; ss >> id; return id; } volatile long start; void wait() { __sync_add_and_fetch(&start,-1); do{}while(start); } volatile long stop; class Hist { public: class Buffer { public: Buffer(Hist & ih) : h(ih), bsize(0){} ~Buffer() {fillFromBuffer();} void fill(int i) { if (100== bsize) fillFromBuffer(); buffer[bsize++]=i; } private: void fillFromBuffer() { Guard g(h.gl); for (int i=0; i!=bsize; ++i) ++h.h[buffer[i]]; bsize=0; } private: Hist & h; int buffer[100]; int bsize; friend class Hist; }; Hist(int nlocks) : locks(new Mutex[nlocks]), stride(256/nlocks){ for (int i=0; i<256; ++i) h[i]=0; } ~Hist() {} void fill(int i) { Guard g(locks[i/stride]); ++h[i]; } std::unique_ptr locks; int stride; int h[256]; // std::atomic h[256]; Mutex gl; }; class Filler { public: Filler(Hist& h) : hist(h){} void operator()() { std::mt19937 eng; std::uniform_int ugen(0,255); eng.seed(threadId()); { Hist::Buffer buffer(hist); wait(); for (int i=0; i<1000000; ++i) { // buffer.fill(ugen(eng)); hist.fill(ugen(eng)); } } __sync_add_and_fetch(&stop,-1); } Hist & hist; }; int main() { const int NUMTHREADS=10; start=NUMTHREADS+1; stop=NUMTHREADS; Hist hist (NUMTHREADS); Filler filler(hist); ThreadGroup threads; threads.reserve(NUMTHREADS); for (int i=0; i(std::cout,",")); std::cout << std::endl; std::cout << "total " << n << std::endl; std::cout << "time filling " << double(tot)/1000. <