public static void RunMany(Benchmarker benchmarker, IEnumerable <int> threadCounts, Action <int> runner) { PrintHeader(); foreach (int i in threadCounts) { runner(i); } }
static void Main(string[] args) { var threads = new [] { 2, 4, 8, 16, 32 }; // 1. ConcurrentQueue.Enqueue Benchmarker.RunMany(threads, i => { var qb = new ConcurrentQueueBenchmarker <int>("ConcurrentQueue.Enqueue", i, (_, cqb) => { for (int j = 0; j < QUEUE_ACTIONS_PER_THREAD; ++j) { cqb.Queue.Enqueue(100); } }); qb.Run(); }); // 2. ConcurrentQueue.TryDequeue Benchmarker.RunMany(threads, i => { var qb = new ConcurrentQueueBenchmarker <int>("ConcurrentQueue.TryDequeue", i, cqb => { for (int j = 0; j < QUEUE_ACTIONS_PER_THREAD; ++j) { cqb.Queue.Enqueue(100); } }, (_, cqb) => { int k; for (int j = 0; j < QUEUE_ACTIONS_PER_THREAD / cqb.NumThreads; ++j) { cqb.Queue.TryDequeue(out k); } }); qb.Run(); }); // 3. Multiple threads enqueue, one thread dequeues Benchmarker.RunMany(threads, i => { var qb = new ConcurrentQueueBenchmarker <int>("ConcurrentQueue (1 thread dequeues)", i, (id, cqb) => { if (id == cqb.NumThreads - 1) { // Dequeuer thread int k; for (int j = 0; j < QUEUE_ACTIONS_PER_THREAD; ++j) { cqb.Queue.TryDequeue(out k); } } else { for (int j = 0; j < QUEUE_ACTIONS_PER_THREAD / (cqb.NumThreads - 1); ++j) { cqb.Queue.Enqueue(100); } } }); qb.Run(); }); // 4. Multiple threads dequeue from an empty queue Benchmarker.RunMany(threads, i => { var qb = new ConcurrentQueueBenchmarker <int>("ConcurrentQueue dequeuing", i, (_, cqb) => { int k; for (int j = 0; j < QUEUE_ACTIONS_PER_THREAD; ++j) { cqb.Queue.TryDequeue(out k); } }); qb.Run(); }); // 1. MultiTailQueue.Enqueue Benchmarker.RunMany(threads, i => { var qb = new MultiTailQueueBenchmarker <int>("MultiTailQueue.Enqueue", i, (_, mtqb) => { for (int j = 0; j < QUEUE_ACTIONS_PER_THREAD; ++j) { mtqb.Queue.Enqueue(100); } }); qb.Run(); }); // 2. MultiTailQueue.TryDequeue Benchmarker.RunMany(threads, i => { var qb = new MultiTailQueueBenchmarker <int>("MultiTailQueue.TryDequeue", i, mtqb => { for (int j = 0; j < QUEUE_ACTIONS_PER_THREAD; ++j) { mtqb.Queue.Enqueue(100); } }, (_, mtqb) => { int k; for (int j = 0; j < QUEUE_ACTIONS_PER_THREAD / mtqb.NumThreads; ++j) { mtqb.Queue.TryDequeue(out k); } }); qb.Run(); }); // 3. Multiple threads enqueue, one thread dequeues Benchmarker.RunMany(threads, i => { var qb = new MultiTailQueueBenchmarker <int>("MultiTailQueue (1 thread dequeues)", i, (id, cqb) => { if (id == cqb.NumThreads - 1) { // Dequeuer thread int k; for (int j = 0; j < QUEUE_ACTIONS_PER_THREAD; ++j) { cqb.Queue.TryDequeue(out k); } } else { for (int j = 0; j < QUEUE_ACTIONS_PER_THREAD / (cqb.NumThreads - 1); ++j) { cqb.Queue.Enqueue(100); } } }); qb.Run(); }); // 4. Multiple threads dequeue from an empty queue Benchmarker.RunMany(threads, i => { var qb = new MultiTailQueueBenchmarker <int>("MultiTailQueue dequeuing", i, (_, mtqb) => { int k; for (int j = 0; j < QUEUE_ACTIONS_PER_THREAD; ++j) { mtqb.Queue.TryDequeue(out k); } }); qb.Run(); }); }