diff --git a/.github/workflows/ci_standard.yaml b/.github/workflows/ci_standard.yaml index 398dc511..895f8c8e 100644 --- a/.github/workflows/ci_standard.yaml +++ b/.github/workflows/ci_standard.yaml @@ -114,6 +114,13 @@ jobs: flag-name: coverage-windows-${{ join(matrix.*, '-') }} fail-on-error: false + - name: Performance Test + shell: pwsh + run: | + dotnet publish ${{ github.workspace }}/Tests/BenchmarkPerformance/BenchmarkPerformance.csproj --configuration Release --framework net8.0 --runtime win-${{ matrix.BuildPlatform }} + ${{ github.workspace }}/Tests/BenchmarkPerformance/bin/Release/net8.0/win-${{ matrix.BuildPlatform }}/publish/BenchmarkPerformance.exe 1 + working-directory: ${{ github.workspace }} + build_linux: runs-on: ubuntu-20.04 @@ -243,6 +250,13 @@ jobs: flag-name: coverage-linux-x64-Release fail-on-error: false + - name: Performance Test + shell: pwsh + run: | + dotnet publish ${{ github.workspace }}/Tests/BenchmarkPerformance/BenchmarkPerformance.csproj --configuration Release --framework net8.0 --runtime linux-x64 + ${{ github.workspace }}/Tests/BenchmarkPerformance/bin/Release/net8.0/linux-x64/publish/BenchmarkPerformance.exe 1 + working-directory: ${{ github.workspace }} + build_macos_x64: runs-on: macos-13 @@ -513,3 +527,5 @@ jobs: carryforward: coverage-windows-x64-Release,coverage-windows-x86-Release,coverage-linux-x64-Release,coverage-macos-x64-Release,coverage-macos-arm64-Release fail-on-error: false + + diff --git a/Tests/BenchmarkPerformance/Configurations/LatencyTestConfiguration.cs b/Tests/BenchmarkPerformance/Configurations/LatencyTestConfiguration.cs index 8c66212d..bf45ab84 100644 --- a/Tests/BenchmarkPerformance/Configurations/LatencyTestConfiguration.cs +++ b/Tests/BenchmarkPerformance/Configurations/LatencyTestConfiguration.cs @@ -1,5 +1,4 @@ -using System.Linq; -using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Configs; using BenchmarkDotNet.Exporters; using BenchmarkDotNet.Exporters.Csv; using BenchmarkDotNet.Jobs; @@ -12,7 +11,11 @@ internal class LatencyTestConfiguration : ManualConfig { public LatencyTestConfiguration() { - AddJob(Job.Default.WithIterationCount(1).WithToolchain(InProcessEmitToolchain.Instance)); + AddJob(Job.Default + .WithIterationCount(10) + .WithUnrollFactor(1) + .WithInvocationCount(1) + .WithToolchain(InProcessEmitToolchain.Instance)); AddColumnProvider(DefaultConfig.Instance.GetColumnProviders().ToArray()); AddColumn(new LatencyAverageColumn()); AddColumn(new LatencyDeviationColumn()); diff --git a/Tests/BenchmarkPerformance/PerformanceTests/LatencyTest.cs b/Tests/BenchmarkPerformance/PerformanceTests/LatencyTest.cs index 804ed156..5f8ad391 100644 --- a/Tests/BenchmarkPerformance/PerformanceTests/LatencyTest.cs +++ b/Tests/BenchmarkPerformance/PerformanceTests/LatencyTest.cs @@ -1,9 +1,11 @@ +using System.Diagnostics.CodeAnalysis; using System.Globalization; using BenchmarkDotNet.Attributes; using OpenDDSharp.BenchmarkPerformance.CustomColumns; namespace OpenDDSharp.BenchmarkPerformance.PerformanceTests; +[SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Global", Justification = "Required by BenchmarkDotNet.")] public class LatencyTest { private OpenDDSharpLatencyTest _openDDSharpLatencyTest; @@ -127,4 +129,4 @@ private void LatencyStatistics(string name) File.WriteAllText(Path.Combine(LatencyNinetyNineColumn.OutputFolder, ninetyNineFile), _latencyHistory[count * 99 / 100].TotalMilliseconds.ToString("0.0000", CultureInfo.InvariantCulture)); } -} \ No newline at end of file +} diff --git a/Tests/BenchmarkPerformance/PerformanceTests/OpenDDSharpLatencyTest.cs b/Tests/BenchmarkPerformance/PerformanceTests/OpenDDSharpLatencyTest.cs index 18ddb8da..33259af9 100644 --- a/Tests/BenchmarkPerformance/PerformanceTests/OpenDDSharpLatencyTest.cs +++ b/Tests/BenchmarkPerformance/PerformanceTests/OpenDDSharpLatencyTest.cs @@ -2,19 +2,21 @@ using OpenDDSharp.DDS; using OpenDDSharp.OpenDDS.DCPS; using CdrWrapper; +using OpenDDSharp.OpenDDS.RTPS; namespace OpenDDSharp.BenchmarkPerformance.PerformanceTests; internal sealed class OpenDDSharpLatencyTest : IDisposable { private const int DOMAIN_ID = 42; + private const string RTPS_DISCOVERY = "RtpsDiscovery"; private readonly ManualResetEventSlim _evt; private readonly Random _random = new (); private readonly int _totalInstances; private readonly int _totalSamples; - private readonly byte[] _payload; private readonly Dictionary _instanceHandles = new(); + private readonly KeyedOctets _sample; private int _count; @@ -35,39 +37,39 @@ public OpenDDSharpLatencyTest(int totalInstances, int totalSamples, ulong totalP _totalSamples = totalSamples; _evt = new ManualResetEventSlim(false); - _payload = new byte[totalPayload]; - _random.NextBytes(_payload); + var payload = new byte[totalPayload]; + _random.NextBytes(payload); InitializeDDSEntities(); - } - public IList Run() - { _count = 0; - var latencyHistory = new List(); - _readerThread.Start(); - var sample = new KeyedOctets + _sample = new KeyedOctets { - ValueField = _payload, + ValueField = payload, }; + } + + public IList Run() + { + var latencyHistory = new List(); for (var i = 1; i <= _totalSamples; i++) { for (var j = 1; j <= _totalInstances; j++) { - sample.KeyField = j.ToString(CultureInfo.InvariantCulture); + _sample.KeyField = j.ToString(CultureInfo.InvariantCulture); if (!_instanceHandles.TryGetValue(j, out var instanceHandle)) { - instanceHandle = _dataWriter.RegisterInstance(sample); + instanceHandle = _dataWriter.RegisterInstance(_sample); _instanceHandles.Add(j, instanceHandle); } var publicationTime = DateTime.UtcNow.Ticks; - _dataWriter.Write(sample, instanceHandle); + _dataWriter.Write(_sample, instanceHandle); _evt.Wait(); @@ -76,7 +78,7 @@ public IList Run() latencyHistory.Add(latency); _evt.Reset(); - }; + } } _readerThread.Join(); @@ -86,6 +88,25 @@ public IList Run() private void InitializeDDSEntities() { + Ace.Init(); + + var disc = new RtpsDiscovery(RTPS_DISCOVERY) + { + SedpMulticast = false, + SedpLocalAddress = "127.0.0.1:0", + SpdpLocalAddress = "127.0.0.1:0", + ResendPeriod = new TimeValue + { + Seconds = 1, + MicroSeconds = 0, + }, + }; + + ParticipantService.Instance.AddDiscovery(disc); + ParticipantService.Instance.DefaultDiscovery = RTPS_DISCOVERY; + ParticipantService.Instance.SetRepoDomain(DOMAIN_ID, RTPS_DISCOVERY); + + _dpf = ParticipantService.Instance.GetDomainParticipantFactory(); var guid = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); @@ -108,8 +129,6 @@ private void InitializeDDSEntities() Seconds = 0, MicroSeconds = 500_000, }, - SendBufferSize = 1048576, - RcvBufferSize = 4194304, }; config.Insert(transport); @@ -134,12 +153,11 @@ private void InitializeDDSEntities() History = { Kind = HistoryQosPolicyKind.KeepLastHistoryQos, - Depth = 10, + Depth = 1, }, }; var dw = _publisher.CreateDataWriter(_topic, dwQos); _dataWriter = new KeyedOctetsDataWriter(dw); - // TransportRegistry.Instance.BindConfig(configName, _dataWriter); var subQos = new SubscriberQos { @@ -153,12 +171,11 @@ private void InitializeDDSEntities() History = { Kind = HistoryQosPolicyKind.KeepLastHistoryQos, - Depth = 10, + Depth = 1, }, }; var dr = _subscriber.CreateDataReader(_topic, drQos); _dataReader = new KeyedOctetsDataReader(dr); - // TransportRegistry.Instance.BindConfig(configName1, _dataReader); _dataWriter.Enable(); _dataReader.Enable(); @@ -214,5 +231,10 @@ public void Dispose() _participant.DeleteContainedEntities(); _dpf.DeleteParticipant(_participant); + + ParticipantService.Instance.Shutdown(); + + Ace.Fini(); + } } \ No newline at end of file diff --git a/Tests/BenchmarkPerformance/PerformanceTests/RtiConnextLatencyTest.cs b/Tests/BenchmarkPerformance/PerformanceTests/RtiConnextLatencyTest.cs index 5832ecbd..3465ea94 100644 --- a/Tests/BenchmarkPerformance/PerformanceTests/RtiConnextLatencyTest.cs +++ b/Tests/BenchmarkPerformance/PerformanceTests/RtiConnextLatencyTest.cs @@ -18,8 +18,8 @@ internal sealed class RtiConnextLatencyTest : IDisposable private readonly Random _random = new (); private readonly int _totalInstances; private readonly int _totalSamples; - private readonly byte[] _payload; private readonly Dictionary _instanceHandles = new(); + private readonly KeyedOctetsTopicType _sample; private int _count; @@ -39,35 +39,37 @@ public RtiConnextLatencyTest(int totalInstances, int totalSamples, ulong totalPa _evt = new ManualResetEventSlim(false); - _payload = new byte[totalPayload]; - _random.NextBytes(_payload); + var payload = new byte[totalPayload]; + _random.NextBytes(payload); InitializeDDSEntities(); + + _count = 0; + + _readerThread.Start(); + + _sample = new KeyedOctetsTopicType(); + _sample.Value.AddRange(payload); } public IList Run() { var latencyHistory = new List(); - _readerThread.Start(); - - var sample = new KeyedOctetsTopicType(); - sample.Value.AddRange(_payload); - for (var i = 1; i <= _totalSamples; i++) { for (var j = 1; j <= _totalInstances; j++) { - sample.Key = j.ToString(CultureInfo.InvariantCulture); + _sample.Key = j.ToString(CultureInfo.InvariantCulture); if (!_instanceHandles.TryGetValue(j, out var instanceHandle)) { - instanceHandle = _dataWriter.RegisterInstance(sample); + instanceHandle = _dataWriter.RegisterInstance(_sample); _instanceHandles.Add(j, instanceHandle); } var publicationTime = DateTime.UtcNow.Ticks; - _dataWriter.Write(sample); + _dataWriter.Write(_sample); _evt.Wait(); @@ -101,6 +103,8 @@ public void Dispose() _participant.DisposeContainedEntities(); _participant.Dispose(); + + DomainParticipantFactory.Instance.Dispose(); } private void InitializeDDSEntities() diff --git a/Tests/BenchmarkPerformance/Program.cs b/Tests/BenchmarkPerformance/Program.cs index 770fb6f4..befcf486 100644 --- a/Tests/BenchmarkPerformance/Program.cs +++ b/Tests/BenchmarkPerformance/Program.cs @@ -1,74 +1,57 @@ using System.Diagnostics; using BenchmarkDotNet.Running; -using CdrWrapper; -using OpenDDSharp; using OpenDDSharp.BenchmarkPerformance.Configurations; using OpenDDSharp.BenchmarkPerformance.PerformanceTests; -using OpenDDSharp.OpenDDS.DCPS; -using OpenDDSharp.OpenDDS.RTPS; - -const int DOMAIN_ID = 42; -const string RTPS_DISCOVERY = "RtpsDiscovery"; var artifactsPath = Path.Combine(Environment.CurrentDirectory, "PerformanceTestArtifacts"); -Ace.Init(); -var disc = new RtpsDiscovery(RTPS_DISCOVERY) +string input; +if (args.Length == 0) { - SedpMulticast = false, - SedpLocalAddress = "127.0.0.1:0", - SpdpLocalAddress = "127.0.0.1:0", - ResendPeriod = new TimeValue - { - Seconds = 1, - MicroSeconds = 0, - }, - Ttl = 1, -}; - -ParticipantService.Instance.AddDiscovery(disc); -ParticipantService.Instance.DefaultDiscovery = RTPS_DISCOVERY; -ParticipantService.Instance.SetRepoDomain(DOMAIN_ID, RTPS_DISCOVERY); - -var test = new OpenDDSharpLatencyTest(1000, 100, 2048); -Stopwatch stopwatch = new(); -stopwatch.Start(); -test.Run(); -stopwatch.Stop(); -test.Dispose(); - -Console.WriteLine($"OpenDDSharp Latency Test {stopwatch.Elapsed.TotalSeconds}"); - -var test1 = new RtiConnextLatencyTest(1000, 100, 2048); -stopwatch.Reset(); -stopwatch.Start(); -test1.Run(); -stopwatch.Stop(); -test1.Dispose(); - -Console.WriteLine($"RTI Connext Latency Test {stopwatch.Elapsed.TotalSeconds}"); - -//Console.WriteLine("Menu: "); -//Console.WriteLine("[1] Latency Performance Test"); -//Console.WriteLine("[2] Throughput Performance Test"); -//Console.WriteLine("Anything else will stop the program."); -//Console.Write("> "); -//var input = Console.ReadLine(); -//Console.WriteLine(); -//switch (input) -//{ -// case "1": -// { -// var config = new LatencyTestConfiguration -// { -// ArtifactsPath = artifactsPath, -// }; -// _ = BenchmarkRunner.Run(config); -// break; -// } -//} + Console.WriteLine("Menu: "); + Console.WriteLine("[1] Latency Performance Test"); + Console.WriteLine("[2] Throughput Performance Test"); + Console.WriteLine("Anything else will stop the program."); + Console.Write("> "); + input = Console.ReadLine(); + Console.WriteLine(); +} +else +{ + input = args[0]; +} -Ace.Fini(); +switch (input) +{ + case "-1": + var test = new OpenDDSharpLatencyTest(1000, 100, 2048); + Stopwatch stopwatch = new(); + stopwatch.Start(); + test.Run(); + stopwatch.Stop(); + test.Dispose(); + + Console.WriteLine($"OpenDDSharp Latency Test {stopwatch.Elapsed.TotalSeconds}"); + + var test1 = new RtiConnextLatencyTest(1000, 100, 2048); + stopwatch.Reset(); + stopwatch.Start(); + test1.Run(); + stopwatch.Stop(); + test1.Dispose(); + + Console.WriteLine($"RTI Connext Latency Test {stopwatch.Elapsed.TotalSeconds}"); + break; + case "1": + { + var config = new LatencyTestConfiguration + { + ArtifactsPath = artifactsPath, + }; + _ = BenchmarkRunner.Run(config); + break; + } +} Console.WriteLine("Press any button to exit the application."); \ No newline at end of file