Skip to content

Instantly share code, notes, and snippets.

@EgorBo
Created October 10, 2021 14:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EgorBo/9c9e85b214e6eefa240d4d017c8751d3 to your computer and use it in GitHub Desktop.
Save EgorBo/9c9e85b214e6eefa240d4d017c8751d3 to your computer and use it in GitHub Desktop.
Volatile-vs-volatile.cs
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics.Arm;
using System.Threading;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Order;
using BenchmarkDotNet.Running;
public class VolatileKeyword
{
private volatile int A;
private volatile int B;
private volatile int C;
private volatile int D;
[MethodImpl(MethodImplOptions.NoInlining)]
public void SetValue()
{
A = 1;
B = 1;
C = 1;
D = 1;
}
[MethodImpl(MethodImplOptions.NoInlining)]
public int GetValue()
{
return A + B + C + D;
}
[MethodImpl(MethodImplOptions.NoInlining)]
public int GetValueInLoop()
{
int sum = 0;
for (int i = 0; i < 1000; i++)
sum += A + B + C + D;
return sum;
}
[MethodImpl(MethodImplOptions.NoInlining)]
public void SetValueInLoop()
{
for (int i = 0; i < 1000; i++)
{
A = i;
B = i;
C = i;
D = i;
}
}
}
public class VolatileClass
{
private int A;
private int B;
private int C;
private int D;
[MethodImpl(MethodImplOptions.NoInlining)]
public void SetValue()
{
Volatile.Write(ref A, 1);
Volatile.Write(ref B, 1);
Volatile.Write(ref C, 1);
Volatile.Write(ref D, 1);
}
[MethodImpl(MethodImplOptions.NoInlining)]
public int GetValue()
{
return Volatile.Read(ref A) +
Volatile.Read(ref B) +
Volatile.Read(ref C) +
Volatile.Read(ref D);
}
[MethodImpl(MethodImplOptions.NoInlining)]
public int GetValueInLoop()
{
int sum = 0;
for (int i = 0; i < 1000; i++)
sum += Volatile.Read(ref A) +
Volatile.Read(ref B) +
Volatile.Read(ref C) +
Volatile.Read(ref D);
return sum;
}
[MethodImpl(MethodImplOptions.NoInlining)]
public void SetValueInLoop()
{
for (int i = 0; i < 1000; i++)
{
Volatile.Write(ref A, i);
Volatile.Write(ref B, i);
Volatile.Write(ref C, i);
Volatile.Write(ref D, i);
}
}
}
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory), CategoriesColumn]
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("IsArm64: " + AdvSimd.Arm64.IsSupported);
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly)
.Run(args, DefaultConfig.Instance.WithOrderer(new DefaultOrderer(SummaryOrderPolicy.Declared)));
}
public IEnumerable<VolatileClass> TestVolatileClass()
{
yield return new VolatileClass();
}
public IEnumerable<VolatileKeyword> TestVolatileKeyword()
{
yield return new VolatileKeyword();
}
[Benchmark]
[ArgumentsSource(nameof(TestVolatileKeyword))]
public void SetValue_volatile(VolatileKeyword v) => v.SetValue();
[Benchmark]
[ArgumentsSource(nameof(TestVolatileClass))]
public void SetValue_VolatileWrite(VolatileClass v) => v.SetValue();
[Benchmark]
[ArgumentsSource(nameof(TestVolatileKeyword))]
public void SetValueInLoop_volatile(VolatileKeyword v) => v.SetValueInLoop();
[Benchmark]
[ArgumentsSource(nameof(TestVolatileClass))]
public void SetValueInLoop_VolatileWrite(VolatileClass v) => v.SetValueInLoop();
[Benchmark]
[ArgumentsSource(nameof(TestVolatileKeyword))]
public int GetValue_volatile(VolatileKeyword v) => v.GetValue();
[Benchmark]
[ArgumentsSource(nameof(TestVolatileClass))]
public int GetValue_VolatileRead(VolatileClass v) => v.GetValue();
[Benchmark]
[ArgumentsSource(nameof(TestVolatileKeyword))]
public int GetValueInLoop_volatile(VolatileKeyword v) => v.GetValueInLoop();
[Benchmark]
[ArgumentsSource(nameof(TestVolatileClass))]
public int GetValueInLoop_VolatileRead(VolatileClass v) => v.GetValueInLoop();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment