Description
There's a performance issue regarding Semaphore in scenarios where threads request and release the semaphore with no work in between as shown in the snippet below. The rate of transactions is up to 3-4 times lower compared to other runtimes.
using System;
using System.Diagnostics;
using System.Threading;
namespace MultiThreadedScaling
{
internal class ScalingIssue
{
static ReaderWriterLockSlim slimRWlock = null;
static Semaphore normalSemaphore = null;
static int numThreads = 8;
static int run_time = 30; // seconds
static void Main(string[] args)
{
Console.WriteLine("Running test with " + numThreads + " threads for " + run_time + " seconds");
slimRWlock = new ReaderWriterLockSlim();
normalSemaphore = new Semaphore(numThreads, Int32.MaxValue);
for (int i = 0; i < numThreads; i++)
{
Thread t1 = new Thread(new ParameterizedThreadStart(OpenCloseSimulation));
t1.Name = i.ToString();
t1.Start(i);
}
}
static void OpenCloseSimulation(object state)
{
int index = (int)state;
int numTxns = 0;
var start_time = DateTime.UtcNow;
while (DateTime.UtcNow - start_time < TimeSpan.FromSeconds(run_time))
{
OpenConnSimulation(index);
CloseConnSimulation(index);
numTxns += 1;
}
var end_time = DateTime.UtcNow;
long totRunTime = (long)(end_time - start_time).TotalSeconds;
Console.WriteLine("Thread " + Thread.CurrentThread.Name + " Transaction rate: commits= " + (numTxns / totRunTime));
}
static void OpenConnSimulation(int index)
{
normalSemaphore.WaitOne();
DoWork();
slimRWlock.EnterReadLock();
DoWork();
slimRWlock.ExitReadLock();
}
static void CloseConnSimulation(int index)
{
DoWork();
normalSemaphore.Release();
}
internal static void DoWork()
{
return;
}
}
}
This scenario was tested with .NET 9, arch x64 for both Windows and Linux. Machines had 16 vcpus and the test was ran using 8 threads during 30 seconds.
The transactions per second rate on Windows is ~320K whereas on Linux the rate is ~130K. Other runtimes can achieve around ~500K+ on both platforms.
Native AOT achieved similar results to the non Native AOT versions.
Description
There's a performance issue regarding Semaphore in scenarios where threads request and release the semaphore with no work in between as shown in the snippet below. The rate of transactions is up to 3-4 times lower compared to other runtimes.
This scenario was tested with .NET 9, arch x64 for both Windows and Linux. Machines had 16 vcpus and the test was ran using 8 threads during 30 seconds.
The transactions per second rate on Windows is ~320K whereas on Linux the rate is ~130K. Other runtimes can achieve around ~500K+ on both platforms.
Native AOT achieved similar results to the non Native AOT versions.