public EventProcessorBenchmarks_Wait() { var waitStrategy = new YieldingWaitStrategy(); var sequencer = new SingleProducerSequencer(64, waitStrategy); var cursorSequence = new Sequence(); var dependentSequences = new ISequence[0]; var sequenceBarrier = new SequenceBarrier(sequencer, waitStrategy, cursorSequence, dependentSequences); var sequenceBarrierClass = new SequenceBarrierClass(sequencer, waitStrategy, cursorSequence, dependentSequences); var sequenceBarrierProxy = StructProxy.CreateProxyInstance(sequenceBarrierClass); var eventProcessorType = typeof(PartialEventProcessor <,>).MakeGenericType(typeof(ISequenceBarrierOptions.IsDependentSequencePublished), sequenceBarrierProxy.GetType()); _processor1 = (IPartialEventProcessor)Activator.CreateInstance(eventProcessorType, sequenceBarrier, sequenceBarrierProxy); _processor2 = new PartialEventProcessor <ISequenceBarrierOptions.IsDependentSequencePublished, SequenceBarrierStruct>(sequenceBarrier, new SequenceBarrierStruct(sequencer, waitStrategy, cursorSequence, dependentSequences)); sequencer.Publish(42); cursorSequence.SetValue(42); }
static void Main(string[] args) { try { if ((args.Length >= 1) && (!int.TryParse(args[0], out _countPerThread)) || (_countPerThread < 1)) { Console.WriteLine(Resources.Strings.UsageMessage); throw new ArgumentException(Resources.Strings.InvalidArgumentCountPerThread); } if ((args.Length >= 2) && (!int.TryParse(args[1], out _producersCount)) || (_producersCount < 1)) { Console.WriteLine(Resources.Strings.UsageMessage); throw new ArgumentException(Resources.Strings.InvalidArgumentProducersCount); } if ((args.Length >= 3) && (!int.TryParse(args[2], out _consumersCount)) || (_consumersCount < 1)) { Console.WriteLine(Resources.Strings.UsageMessage); throw new ArgumentException(Resources.Strings.InvalidArgumentConsumersCount); } _countPerThread = _countPerThread / _producersCount; _totalCount = _countPerThread * _producersCount; var stopWatchProduce = Stopwatch.StartNew(); var stopWatchTotal = Stopwatch.StartNew(); var results = new double[_totalCount]; for (var i = 0; i < _totalCount; i++) { results[i] = 0; } const int disruptorBufferSize = 1024; var disruptorClaimStrategy = (_producersCount == 1) ? new SingleThreadedClaimStrategy(disruptorBufferSize) : ((_producersCount < Environment.ProcessorCount) ? new MultiThreadedLowContentionClaimStrategy(disruptorBufferSize) as IClaimStrategy : new MultiThreadedClaimStrategy(disruptorBufferSize)); var disruptorWaitStrategy = new YieldingWaitStrategy(); var collection = new Disruptor <ValueEntry>(() => new ValueEntry(), disruptorClaimStrategy, disruptorWaitStrategy, TaskScheduler.Default); for (var i = 0; i < _consumersCount; i++) { collection.HandleEventsWith(new Consumer(i, stopWatchTotal, results)); } // Create ring buffer. var ringBuffer = collection.Start(); // Restart stopwatch timers. stopWatchProduce.Restart(); stopWatchTotal.Restart(); // Create and start producer tasks. var producers = new Task[_producersCount]; for (var producerIndex = 0; producerIndex < _producersCount; producerIndex++) { producers[producerIndex] = Task.Factory.StartNew(state => { var index = (int)state; for (var i = 0; i < _countPerThread; i++) { var sequenceNo = ringBuffer.Next(); var value = ringBuffer[sequenceNo]; value.Index = index * _countPerThread + i; value.Value = stopWatchTotal.ElapsedTicks; // Console.WriteLine(Resources.Strings.ProduceMessage, value.Index, index); ringBuffer.Publish(sequenceNo); } }, producerIndex, TaskCreationOptions.LongRunning); } // Wait for producing complete. Task.WaitAll(producers); stopWatchProduce.Stop(); // Wait for consuming complete. collection.Shutdown(); stopWatchTotal.Stop(); // Adjust result table. var frequency = Stopwatch.Frequency / (1000.0 * 1000.0); for (var i = 0; i < _totalCount; i++) { results[i] /= frequency; } Array.Sort(results); // Show report messages. var throughputProduce = _totalCount / ((double)stopWatchProduce.ElapsedTicks / Stopwatch.Frequency); Console.WriteLine(Resources.Strings.ReportMessageForProducers, _totalCount, stopWatchProduce.ElapsedMilliseconds, throughputProduce); var throughputTotal = _totalCount / ((double)stopWatchTotal.ElapsedTicks / Stopwatch.Frequency); Console.WriteLine(Resources.Strings.ReportMessageForConsumers, _totalCount, stopWatchTotal.ElapsedMilliseconds, throughputTotal); // Show latency histogram. ShowHistogram(results, 10); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { // Wait for user stop action. Console.WriteLine(Resources.Strings.StopMessage); Console.ReadKey(); } }
public void StartProcessing() { // Check the processing started flag. if (IsProcessing) { throw new InvalidOperationException(Resources.Strings.AsyncQueueStartError); } _claimStrategy = ClaimStrategy; _waitStrategy = WaitStrategy; _bufferSize = Math.Max(128, BufferSize); // Reset asynchronous queue size. Interlocked.Exchange(ref _asyncQueueSize, 0); IClaimStrategy disruptorClaimStrategy; switch (_claimStrategy) { case ClaimStrategyType.SingleThreaded: disruptorClaimStrategy = new SingleThreadedClaimStrategy(_bufferSize); break; case ClaimStrategyType.MultiThreaded: disruptorClaimStrategy = new MultiThreadedClaimStrategy(_bufferSize); break; case ClaimStrategyType.MultiThreadedLowContention: disruptorClaimStrategy = new MultiThreadedLowContentionClaimStrategy(_bufferSize); break; default: disruptorClaimStrategy = new MultiThreadedClaimStrategy(_bufferSize); break; } IWaitStrategy disruptorWaitStrategy; switch (_waitStrategy) { case WaitStrategyType.Blocking: disruptorWaitStrategy = new BlockingWaitStrategy(); break; case WaitStrategyType.BusySpin: disruptorWaitStrategy = new BusySpinWaitStrategy(); break; case WaitStrategyType.Sleeping: disruptorWaitStrategy = new SleepingWaitStrategy(); break; case WaitStrategyType.Yielding: disruptorWaitStrategy = new YieldingWaitStrategy(); break; default: disruptorWaitStrategy = new YieldingWaitStrategy(); break; } // Initialize processing consumer. _processingConsumer = new ProcessingConsumer(this); // Initialize processing disruptor. _processingDisruptor = new Disruptor <ValueEntry>(() => new ValueEntry(), disruptorClaimStrategy, disruptorWaitStrategy, TaskScheduler.Default); _processingDisruptor.HandleEventsWith(_processingConsumer); // Create ring buffer. _processingRingBuffer = _processingDisruptor.Start(); // Set the processing started flag. IsProcessing = true; // Rise asynchronous processing start event. HandleStart(); }