Skip to content

Commit

Permalink
Make wait strategy configurable in perf tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ocoanet committed Dec 7, 2024
1 parent 20b5f2e commit 58653cd
Show file tree
Hide file tree
Showing 17 changed files with 62 additions and 125 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class OneWaySequencedLatencyTest : ILatencyTest, IDisposable
public OneWaySequencedLatencyTest(ProgramOptions options)
{
_options = options;
_disruptor = new Disruptor<PerfEvent>(() => new PerfEvent(), _bufferSize, new YieldingWaitStrategy());
_disruptor = new Disruptor<PerfEvent>(() => new PerfEvent(), _bufferSize, options.GetWaitStrategy());
_handler = new Handler(options.GetCustomCpu(1));
_disruptor.HandleEventsWith(_handler);
_disruptor.Start();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class OneWaySequencedLatencyTest_BatchHandler : ILatencyTest, IDisposable
public OneWaySequencedLatencyTest_BatchHandler(ProgramOptions options)
{
_options = options;
_disruptor = new Disruptor<PerfEvent>(() => new PerfEvent(), _bufferSize, new YieldingWaitStrategy());
_disruptor = new Disruptor<PerfEvent>(() => new PerfEvent(), _bufferSize, options.GetWaitStrategy());
_handler = new Handler(options.GetCustomCpu(1));
_disruptor.HandleEventsWith(_handler);
_disruptor.Start();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ public class PingPongSequencedLatencyTest : ILatencyTest

public PingPongSequencedLatencyTest(ProgramOptions options)
{
var pingBuffer = RingBuffer<PerfEvent>.CreateSingleProducer(PerfEvent.EventFactory, _bufferSize, new YieldingWaitStrategy());
var pongBuffer = RingBuffer<PerfEvent>.CreateSingleProducer(PerfEvent.EventFactory, _bufferSize, new YieldingWaitStrategy());
var pingBuffer = RingBuffer<PerfEvent>.CreateSingleProducer(PerfEvent.EventFactory, _bufferSize, options.GetWaitStrategy());
var pongBuffer = RingBuffer<PerfEvent>.CreateSingleProducer(PerfEvent.EventFactory, _bufferSize, options.GetWaitStrategy());

var pingBarrier = pingBuffer.NewBarrier();
var pongBarrier = pongBuffer.NewBarrier();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ public class PingPongSequencedLatencyTest_BatchHandler : ILatencyTest

public PingPongSequencedLatencyTest_BatchHandler(ProgramOptions options)
{
var pingBuffer = RingBuffer<PerfEvent>.CreateSingleProducer(PerfEvent.EventFactory, _bufferSize, new YieldingWaitStrategy());
var pongBuffer = RingBuffer<PerfEvent>.CreateSingleProducer(PerfEvent.EventFactory, _bufferSize, new YieldingWaitStrategy());
var pingBuffer = RingBuffer<PerfEvent>.CreateSingleProducer(PerfEvent.EventFactory, _bufferSize, options.GetWaitStrategy());
var pongBuffer = RingBuffer<PerfEvent>.CreateSingleProducer(PerfEvent.EventFactory, _bufferSize, options.GetWaitStrategy());

var pingBarrier = pingBuffer.NewBarrier();
var pongBarrier = pongBuffer.NewBarrier();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ public class PingPongSequencedLatencyTest_Multi : ILatencyTest

public PingPongSequencedLatencyTest_Multi(ProgramOptions options)
{
var pingBuffer = RingBuffer<PerfEvent>.CreateMultiProducer(PerfEvent.EventFactory, _bufferSize, new YieldingWaitStrategy());
var pongBuffer = RingBuffer<PerfEvent>.CreateMultiProducer(PerfEvent.EventFactory, _bufferSize, new YieldingWaitStrategy());
var pingBuffer = RingBuffer<PerfEvent>.CreateMultiProducer(PerfEvent.EventFactory, _bufferSize, options.GetWaitStrategy());
var pongBuffer = RingBuffer<PerfEvent>.CreateMultiProducer(PerfEvent.EventFactory, _bufferSize, options.GetWaitStrategy());

var pingBarrier = pingBuffer.NewBarrier();
var pongBarrier = pongBuffer.NewBarrier();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ public class PingPongSequencedLatencyTest_Value : ILatencyTest

public PingPongSequencedLatencyTest_Value(ProgramOptions options)
{
var pingBuffer = ValueRingBuffer<PerfValueEvent>.CreateSingleProducer(PerfValueEvent.EventFactory, _bufferSize, new BlockingWaitStrategy());
var pongBuffer = ValueRingBuffer<PerfValueEvent>.CreateSingleProducer(PerfValueEvent.EventFactory, _bufferSize, new BlockingWaitStrategy());
var pingBuffer = ValueRingBuffer<PerfValueEvent>.CreateSingleProducer(PerfValueEvent.EventFactory, _bufferSize, options.GetWaitStrategy());
var pongBuffer = ValueRingBuffer<PerfValueEvent>.CreateSingleProducer(PerfValueEvent.EventFactory, _bufferSize, options.GetWaitStrategy());

var pingBarrier = pingBuffer.NewBarrier();
var pongBarrier = pongBuffer.NewBarrier();
Expand Down
33 changes: 32 additions & 1 deletion src/Disruptor.PerfTests/ProgramOptions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
Expand All @@ -11,6 +12,14 @@ public class ProgramOptions
public static int DefaultRunCountForThroughputTest { get; } = 7;
public static int[] DefaultCpuSet { get; } = Enumerable.Range(0, Environment.ProcessorCount).ToArray();

public static IReadOnlyDictionary<string, Func<IWaitStrategy>> ConfigurableWaitStrategies { get; } = new Dictionary<string, Func<IWaitStrategy>>(StringComparer.OrdinalIgnoreCase)

{
["yielding"] = () => new YieldingWaitStrategy(),
["blocking"] = () => new BlockingWaitStrategy(),
["busy-spin"] = () => new BusySpinWaitStrategy(),
};

private int[] _cpuSet = DefaultCpuSet;

public int? RunCount { get; private set; }
Expand All @@ -35,9 +44,20 @@ private set

public bool HasCustomCpuSet { get; private set; }

public Func<IWaitStrategy> WaitStrategySource { get; set; }

public int RunCountForLatencyTest => RunCount ?? DefaultRunCountForLatencyTest;
public int RunCountForThroughputTest => RunCount ?? DefaultRunCountForThroughputTest;
public int? GetCustomCpu(int index) => HasCustomCpuSet ? CpuSet[index] : null;

public int? GetCustomCpu(int index)
=> HasCustomCpuSet ? CpuSet[index] : null;

public IWaitStrategy GetWaitStrategy()
=> GetWaitStrategy<YieldingWaitStrategy>();

public IWaitStrategy GetWaitStrategy<TDefault>()
where TDefault : IWaitStrategy, new()
=> WaitStrategySource != null ? WaitStrategySource.Invoke() : new TDefault();

public static bool TryParse(string[] args, out ProgramOptions options)
{
Expand Down Expand Up @@ -147,6 +167,16 @@ public static bool TryParse(string[] args, out ProgramOptions options)
continue;
}

if (arg.Equals("--wait-strategy", StringComparison.OrdinalIgnoreCase))
{
if (index + 1 == args.Length || !ConfigurableWaitStrategies.TryGetValue(args[index + 1], out var waitStrategy))
return false;

options.WaitStrategySource = waitStrategy;
index++;
continue;
}

return false;
}

Expand All @@ -171,6 +201,7 @@ public static void PrintUsage()
Console.WriteLine($" --include-latency <true|false> Includes latency tests. Default is {options.IncludeLatency}.");
Console.WriteLine($" --include-throughput <true|false> Includes throughput tests. Default is {options.IncludeThroughput}.");
Console.WriteLine($" --cpus <cpu-set> The comma-separated list of CPUs to use for CPU affinity (not supported in all tests).");
Console.WriteLine($" --wait-strategy <type> The disruptor wait strategy. Supported values: {string.Join(", ", ConfigurableWaitStrategies.Keys)}. (not supported in all tests).");
Console.WriteLine();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ public class OneToOneSequencedThroughputTest_BatchHandler : IThroughputTest
private readonly long _expectedResult = PerfTestUtil.AccumulatedAddition(_iterations);
private readonly IEventProcessor<PerfEvent> _eventProcessor;

public OneToOneSequencedThroughputTest_BatchHandler()
public OneToOneSequencedThroughputTest_BatchHandler(ProgramOptions options)
{
_eventHandler = new AdditionBatchEventHandler();
_ringBuffer = RingBuffer<PerfEvent>.CreateSingleProducer(PerfEvent.EventFactory, _bufferSize, new YieldingWaitStrategy());
_ringBuffer = RingBuffer<PerfEvent>.CreateSingleProducer(PerfEvent.EventFactory, _bufferSize, options.GetWaitStrategy());
var sequenceBarrier = _ringBuffer.NewBarrier();
_eventProcessor = EventProcessorFactory.Create(_ringBuffer, sequenceBarrier, _eventHandler);
_ringBuffer.AddGatingSequences(_eventProcessor.Sequence);
Expand Down Expand Up @@ -86,4 +86,4 @@ public long Run(ThroughputSessionContext sessionContext)

return _iterations;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ public class OneToOneSequencedThroughputTest_BatchHandler_BatchPublisher : IThro
private readonly AdditionBatchEventHandler _handler;
private readonly IEventProcessor<PerfEvent> _eventProcessor;

public OneToOneSequencedThroughputTest_BatchHandler_BatchPublisher()
public OneToOneSequencedThroughputTest_BatchHandler_BatchPublisher(ProgramOptions options)
{
_ringBuffer = RingBuffer<PerfEvent>.CreateSingleProducer(PerfEvent.EventFactory, _bufferSize, new YieldingWaitStrategy());
_ringBuffer = RingBuffer<PerfEvent>.CreateSingleProducer(PerfEvent.EventFactory, _bufferSize, options.GetWaitStrategy());
var sequenceBarrier = _ringBuffer.NewBarrier();
_handler = new AdditionBatchEventHandler();
_eventProcessor = EventProcessorFactory.Create(_ringBuffer, sequenceBarrier, _handler);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public OneToOneSequencedThroughputTest(ProgramOptions options)
{
_options = options;
_eventHandler = new AdditionEventHandler(options.GetCustomCpu(1));
_ringBuffer = RingBuffer<PerfEvent>.CreateSingleProducer(PerfEvent.EventFactory, _bufferSize, new YieldingWaitStrategy());
_ringBuffer = RingBuffer<PerfEvent>.CreateSingleProducer(PerfEvent.EventFactory, _bufferSize, options.GetWaitStrategy());
var sequenceBarrier = _ringBuffer.NewBarrier();
_eventProcessor = EventProcessorFactory.Create(_ringBuffer, sequenceBarrier, _eventHandler);
_ringBuffer.AddGatingSequences(_eventProcessor.Sequence);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public OneToOneSequencedThroughputTest_BatchPublisher(ProgramOptions options)
{
_options = options;
_handler = new AdditionEventHandler(options.GetCustomCpu(1));
_ringBuffer = RingBuffer<PerfEvent>.CreateSingleProducer(PerfEvent.EventFactory, _bufferSize, new YieldingWaitStrategy());
_ringBuffer = RingBuffer<PerfEvent>.CreateSingleProducer(PerfEvent.EventFactory, _bufferSize, options.GetWaitStrategy());
var sequenceBarrier = _ringBuffer.NewBarrier();
_eventProcessor = EventProcessorFactory.Create(_ringBuffer, sequenceBarrier, _handler);
_ringBuffer.AddGatingSequences(_eventProcessor.Sequence);
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public OneToOneSequencedThroughputTest_Multi(ProgramOptions options)
{
_options = options;
_eventHandler = new AdditionEventHandler(options.GetCustomCpu(1));
_ringBuffer = RingBuffer<PerfEvent>.CreateMultiProducer(PerfEvent.EventFactory, _bufferSize, new YieldingWaitStrategy());
_ringBuffer = RingBuffer<PerfEvent>.CreateMultiProducer(PerfEvent.EventFactory, _bufferSize, options.GetWaitStrategy());
var sequenceBarrier = _ringBuffer.NewBarrier();
_eventProcessor = EventProcessorFactory.Create(_ringBuffer, sequenceBarrier, _eventHandler);
_ringBuffer.AddGatingSequences(_eventProcessor.Sequence);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ public class OneToOneSequencedThroughputTest_Unmanaged : IThroughputTest
private readonly IValueEventProcessor<PerfValueEvent> _eventProcessor;
private readonly UnmanagedRingBufferMemory _memory;

public OneToOneSequencedThroughputTest_Unmanaged()
public OneToOneSequencedThroughputTest_Unmanaged(ProgramOptions options)
{
_eventHandler = new AdditionEventHandler();
_memory = UnmanagedRingBufferMemory.Allocate(_bufferSize, PerfValueEvent.Size);
_ringBuffer = new UnmanagedRingBuffer<PerfValueEvent>(_memory, ProducerType.Single, new YieldingWaitStrategy());
_ringBuffer = new UnmanagedRingBuffer<PerfValueEvent>(_memory, ProducerType.Single, options.GetWaitStrategy());
var sequenceBarrier = _ringBuffer.NewBarrier();
_eventProcessor = EventProcessorFactory.Create(_ringBuffer, sequenceBarrier, _eventHandler);
_ringBuffer.AddGatingSequences(_eventProcessor.Sequence);
Expand Down Expand Up @@ -86,4 +86,4 @@ public long Run(ThroughputSessionContext sessionContext)

return _iterations;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ public class OneToOneSequencedThroughputTest_Unmanaged_BatchPublisher : IThrough
private readonly IValueEventProcessor<PerfValueEvent> _eventProcessor;
private readonly UnmanagedRingBufferMemory _memory;

public OneToOneSequencedThroughputTest_Unmanaged_BatchPublisher()
public OneToOneSequencedThroughputTest_Unmanaged_BatchPublisher(ProgramOptions options)
{
_memory = UnmanagedRingBufferMemory.Allocate(_bufferSize, PerfValueEvent.Size);
_ringBuffer = new UnmanagedRingBuffer<PerfValueEvent>(_memory, ProducerType.Single,new YieldingWaitStrategy());
_ringBuffer = new UnmanagedRingBuffer<PerfValueEvent>(_memory, ProducerType.Single, options.GetWaitStrategy());
var sequenceBarrier = _ringBuffer.NewBarrier();
_handler = new AdditionEventHandler();
_eventProcessor = EventProcessorFactory.Create(_ringBuffer, sequenceBarrier, _handler);
Expand Down Expand Up @@ -96,4 +96,4 @@ public long Run(ThroughputSessionContext sessionContext)

return _batchSize * _iterations;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ public class OneToOneSequencedThroughputTest_Value : IThroughputTest
private readonly long _expectedResult = PerfTestUtil.AccumulatedAddition(_iterations);
private readonly IValueEventProcessor<PerfValueEvent> _eventProcessor;

public OneToOneSequencedThroughputTest_Value()
public OneToOneSequencedThroughputTest_Value(ProgramOptions options)
{
_eventHandler = new AdditionEventHandler();
_ringBuffer = ValueRingBuffer<PerfValueEvent>.CreateSingleProducer(PerfValueEvent.EventFactory, _bufferSize, new YieldingWaitStrategy());
_ringBuffer = ValueRingBuffer<PerfValueEvent>.CreateSingleProducer(PerfValueEvent.EventFactory, _bufferSize, options.GetWaitStrategy());
var sequenceBarrier = _ringBuffer.NewBarrier();
_eventProcessor = EventProcessorFactory.Create(_ringBuffer, sequenceBarrier, _eventHandler);
_ringBuffer.AddGatingSequences(_eventProcessor.Sequence);
Expand Down Expand Up @@ -83,4 +83,4 @@ public long Run(ThroughputSessionContext sessionContext)

return _iterations;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ public class OneToOneSequencedThroughputTest_Value_BatchPublisher : IThroughputT
private readonly AdditionEventHandler _handler;
private readonly IValueEventProcessor<PerfValueEvent> _eventProcessor;

public OneToOneSequencedThroughputTest_Value_BatchPublisher()
public OneToOneSequencedThroughputTest_Value_BatchPublisher(ProgramOptions options)
{
_ringBuffer = ValueRingBuffer<PerfValueEvent>.CreateSingleProducer(PerfValueEvent.EventFactory, _bufferSize, new YieldingWaitStrategy());
_ringBuffer = ValueRingBuffer<PerfValueEvent>.CreateSingleProducer(PerfValueEvent.EventFactory, _bufferSize, options.GetWaitStrategy());
var sequenceBarrier = _ringBuffer.NewBarrier();
_handler = new AdditionEventHandler();
_eventProcessor = EventProcessorFactory.Create(_ringBuffer, sequenceBarrier, _handler);
Expand Down Expand Up @@ -93,4 +93,4 @@ public long Run(ThroughputSessionContext sessionContext)

return _batchSize * _iterations;
}
}
}

0 comments on commit 58653cd

Please sign in to comment.