Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
ikopylov committed Sep 24, 2020
2 parents 7c396cb + b4e29b2 commit 8622c62
Show file tree
Hide file tree
Showing 63 changed files with 3,456 additions and 358 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ Library contains a number of reuseful base classes:
14. [Read only collections](https://github.com/qoollo/system-class-library/wiki/Read-only-collections) - a number of useful readonly collections (List, Dictionary, HashSet);
15. [A bunch of extension methods](https://github.com/qoollo/system-class-library/wiki/Extension-Methods) for ```IEnumerable<T>```, ```Type```, ```Exception```;
16. [MonitorObject](https://github.com/qoollo/dotNet-turbo/wiki/MonitorObject) - object oriented abstraction over BCL ```Monitor.Wait()```, ```Monitor.Pulse()```, ```Monitor.PulseAll()```;
17. [Queues](https://github.com/qoollo/dotNet-turbo/wiki/Queues) - exposes 4 types of thread-safe blocking queues: ```MemoryQueue<T>```, ```DiskQueue<T>```, ```TransformationQueue<T>``` and ```LevelingQueue<T>```.
17. [Queues](https://github.com/qoollo/dotNet-turbo/wiki/Queues) - exposes 4 types of thread-safe blocking queues: ```MemoryQueue<T>```, ```DiskQueue<T>```, ```TransformationQueue<T>``` and ```LevelingQueue<T>```;
18. [BatchingQueue](https://github.com/qoollo/dotNet-turbo/wiki/BatchingQueue) - queue in which items are enqueued one-by-one and dequeued in batches. Exposes `ConcurrentBatchingQueue<T>` and `BlockingBatchingQueue<T>`.

## NuGet
[Qoollo.Turbo](https://www.nuget.org/packages/Qoollo.Turbo/)
5 changes: 5 additions & 0 deletions ReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
v3.1.0 (24.09.2020)
- ConcurrentBatchingQueue and BlockingBatchingQueue added
- SpinWait normalization added
- Native .NET Core 3.1 support

v3.0.1 (28.02.2018)
- .NET Core 2.0 support through .NET Standard 2.0
- Public surface comments translated to English
Expand Down
80 changes: 80 additions & 0 deletions src/Qoollo.Turbo.PerformanceTests/ConcurrentBatchingQueueTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using Qoollo.Turbo.Collections.Concurrent;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading;

namespace Qoollo.Turbo.PerformanceTests
{
public static class ConcurrentBatchingQueueTests
{
private static void TestEnqueueOnly(int elemCount, int threadCount, int batchSize, bool useRandom)
{
ConcurrentBatchingQueue<long> q = new ConcurrentBatchingQueue<long>(batchSize);

int atomicRandom = 0;

int trackElemCount = elemCount;
int addFinished = 0;

Thread[] threadsAdd = new Thread[threadCount];

Action addAction = () =>
{
Random rnd = null;
if (useRandom)
rnd = new Random(Environment.TickCount + Interlocked.Increment(ref atomicRandom) * threadCount * 2);

while (true)
{
int item = Interlocked.Decrement(ref trackElemCount);
if (item < 0)
break;

q.Enqueue(item);

int sleepTime = 0;
if (rnd != null)
sleepTime = rnd.Next(elemCount / 10000) - elemCount / 10000 + 2;
if (sleepTime > 0)
Thread.Sleep(sleepTime);
}

Interlocked.Increment(ref addFinished);
};


for (int i = 0; i < threadsAdd.Length; i++)
threadsAdd[i] = new Thread(new ThreadStart(addAction));

Stopwatch sw = Stopwatch.StartNew();

for (int i = 0; i < threadsAdd.Length; i++)
threadsAdd[i].Start();


for (int i = 0; i < threadsAdd.Length; i++)
threadsAdd[i].Join();


sw.Stop();

Console.WriteLine($"ThreadCount: {threadCount}, ElementCount: {elemCount}, BatchSize: {batchSize}, Time: {sw.ElapsedMilliseconds}ms");
}

public static void RunTest()
{
for (int i = 0; i < 10; i++)
{
TestEnqueueOnly(20000000, 1, 32, false);
TestEnqueueOnly(20000000, 2, 32, false);
TestEnqueueOnly(20000000, 8, 32, false);
TestEnqueueOnly(20000000, 8, 1024, false);
TestEnqueueOnly(10000000, 4, 1, false);

Console.WriteLine();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Qoollo.Turbo.Threading;
using Qoollo.Turbo.Threading.ServiceStuff;
using System;
using System.Collections.Generic;
using System.Diagnostics;
Expand Down Expand Up @@ -105,7 +106,7 @@ private static TimeSpan MeasureNormalProc(int count, int thCount, int spin)

while (Interlocked.Increment(ref value) < count)
{
Thread.SpinWait(spin);
SpinWaitHelper.SpinWait(spin);
}

barEnd.SignalAndWait();
Expand Down Expand Up @@ -147,7 +148,7 @@ private static TimeSpan MeasureCountingProc(int count, int thCount, int spin)
{
using (var guard = inst.TryEnter())
{
Thread.SpinWait(spin);
SpinWaitHelper.SpinWait(spin);
}
}

Expand Down Expand Up @@ -182,8 +183,8 @@ public static void RunTest()
{
for (int i = 0; i < 10; i++)
{
MeasureNormalProc(50000000, 4, 25);
MeasureCountingProc(50000000, 4, 25);
MeasureNormalProc(50000000, 4, 5);
MeasureCountingProc(50000000, 4, 5);

Console.WriteLine();
}
Expand Down
62 changes: 33 additions & 29 deletions src/Qoollo.Turbo.PerformanceTests/HighConcurrencyLoadTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Qoollo.Turbo.Collections.Concurrent;
using Qoollo.Turbo.Threading.ServiceStuff;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
Expand Down Expand Up @@ -209,7 +210,7 @@ private static TimeSpan RunConcurrentBC(string name, int elemCount, int addThCou
while ((index = Interlocked.Increment(ref addedElemCount)) <= elemCount)
{
col.Add(index - 1);
Thread.SpinWait(addSpin);
SpinWaitHelper.SpinWait(addSpin);
}

barierAdders.SignalAndWait();
Expand All @@ -231,7 +232,7 @@ private static TimeSpan RunConcurrentBC(string name, int elemCount, int addThCou
val = col.Take(myToken);

valList.Add(val);
Thread.SpinWait(takeSpin);
SpinWaitHelper.SpinWait(takeSpin);
}
}
catch (OperationCanceledException)
Expand Down Expand Up @@ -316,7 +317,7 @@ private static TimeSpan RunConcurrentBQ(string name, int elemCount, int addThCou
while ((index = Interlocked.Increment(ref addedElemCount)) <= elemCount)
{
col.Add(index - 1);
Thread.SpinWait(addSpin);
SpinWaitHelper.SpinWait(addSpin);
}

barierAdders.SignalAndWait();
Expand All @@ -338,7 +339,7 @@ private static TimeSpan RunConcurrentBQ(string name, int elemCount, int addThCou
val = col.Take(myToken);

valList.Add(val);
Thread.SpinWait(takeSpin);
SpinWaitHelper.SpinWait(takeSpin);
}
}
catch (OperationCanceledException)
Expand Down Expand Up @@ -425,7 +426,7 @@ private static TimeSpan RunConcurrentCondVar(string name, int elemCount, int add
while ((index = Interlocked.Increment(ref addedElemCount)) <= elemCount)
{
col.Add(index - 1);
Thread.SpinWait(addSpin);
SpinWaitHelper.SpinWait(addSpin);
}

barierAdders.SignalAndWait();
Expand All @@ -447,7 +448,7 @@ private static TimeSpan RunConcurrentCondVar(string name, int elemCount, int add
val = col.Take(myToken);

valList.Add(val);
Thread.SpinWait(takeSpin);
SpinWaitHelper.SpinWait(takeSpin);
}
}
catch (OperationCanceledException)
Expand Down Expand Up @@ -535,7 +536,7 @@ private static TimeSpan RunConcurrentMon(string name, int elemCount, int addThCo
while ((index = Interlocked.Increment(ref addedElemCount)) <= elemCount)
{
col.Add(index - 1);
Thread.SpinWait(addSpin);
SpinWaitHelper.SpinWait(addSpin);
}

barierAdders.SignalAndWait();
Expand All @@ -557,7 +558,7 @@ private static TimeSpan RunConcurrentMon(string name, int elemCount, int addThCo
val = col.Take(myToken);

valList.Add(val);
Thread.SpinWait(takeSpin);
SpinWaitHelper.SpinWait(takeSpin);
}
}
catch (OperationCanceledException)
Expand Down Expand Up @@ -736,76 +737,79 @@ public static void RunTest()
//TstBQ();

//Process.GetCurrentProcess().ProcessorAffinity = (IntPtr)1;
SpinWaitHelper.WaitUntilNormalizationCoefCalculated();
Console.WriteLine($"SpinWait norm coef = {SpinWaitHelper.NormalizationCoef}");


for (int i = 0; i < 10; i++)
{
RunConcurrentBC("1, 1", 5000000, 1, 1, 10, 10);

RunConcurrentBC("1, 1", 5000000, 1, 1, 20, 20);
Free();

RunConcurrentBC("4, 4", 5000000, 4, 4, 10, 10);
RunConcurrentBC("4, 4", 5000000, 4, 4, 20, 20);
Free();

RunConcurrentBC("16, 1", 5000000, 16, 1, 10, 10);
RunConcurrentBC("16, 1", 5000000, 16, 1, 20, 20);
Free();

RunConcurrentBC("1, 16", 5000000, 1, 16, 10, 10);
RunConcurrentBC("1, 16", 5000000, 1, 16, 20, 20);
Free();

RunConcurrentBC("16, 16", 5000000, 16, 16, 10, 10);
RunConcurrentBC("16, 16", 5000000, 16, 16, 20, 20);
Free();

Console.WriteLine();

RunConcurrentBQ("1, 1", 5000000, 1, 1, 10, 10);
RunConcurrentBQ("1, 1", 5000000, 1, 1, 20, 20);
Free();

RunConcurrentBQ("4, 4", 5000000, 4, 4, 10, 10);
RunConcurrentBQ("4, 4", 5000000, 4, 4, 20, 20);
Free();

RunConcurrentBQ("16, 1", 5000000, 16, 1, 10, 10);
RunConcurrentBQ("16, 1", 5000000, 16, 1, 20, 20);
Free();

RunConcurrentBQ("1, 16", 5000000, 1, 16, 10, 10);
RunConcurrentBQ("1, 16", 5000000, 1, 16, 20, 20);
Free();

RunConcurrentBQ("16, 16", 5000000, 16, 16, 10, 10);
RunConcurrentBQ("16, 16", 5000000, 16, 16, 20, 20);
Free();

Console.WriteLine();

RunConcurrentCondVar("1, 1", 5000000, 1, 1, 10, 10);
RunConcurrentCondVar("1, 1", 5000000, 1, 1, 20, 20);
Free();

RunConcurrentCondVar("4, 4", 5000000, 4, 4, 10, 10);
RunConcurrentCondVar("4, 4", 5000000, 4, 4, 20, 20);
Free();

RunConcurrentCondVar("16, 1", 5000000, 16, 1, 10, 10);
RunConcurrentCondVar("16, 1", 5000000, 16, 1, 20, 20);
Free();

RunConcurrentCondVar("1, 16", 5000000, 1, 16, 10, 10);
RunConcurrentCondVar("1, 16", 5000000, 1, 16, 20, 20);
Free();

RunConcurrentCondVar("16, 16", 5000000, 16, 16, 10, 10);
RunConcurrentCondVar("16, 16", 5000000, 16, 16, 20, 20);
Free();

Console.WriteLine();

RunConcurrentMon("1, 1", 5000000, 1, 1, 10, 10);
RunConcurrentMon("1, 1", 5000000, 1, 1, 20, 20);
Free();

RunConcurrentMon("4, 4", 5000000, 4, 4, 10, 10);
RunConcurrentMon("4, 4", 5000000, 4, 4, 20, 20);
Free();

RunConcurrentMon("16, 1", 5000000, 16, 1, 10, 10);
RunConcurrentMon("16, 1", 5000000, 16, 1, 20, 20);
Free();

RunConcurrentMon("1, 16", 5000000, 1, 16, 10, 10);
RunConcurrentMon("1, 16", 5000000, 1, 16, 20, 20);
Free();

RunConcurrentMon("16, 16", 5000000, 16, 16, 10, 10);
RunConcurrentMon("16, 16", 5000000, 16, 16, 20, 20);
Free();


//RunConcurrentBC("Simple", 5000000, /*Environment.ProcessorCount */ 2, 2, 10, 100);//100 / Environment.ProcessorCount, 101);
//Free();

Expand Down
Loading

0 comments on commit 8622c62

Please sign in to comment.