|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Threading;
using System.Runtime.InteropServices;
namespace FalseSharingDemo
{
class Worker
{
const int ITERS = ( int ) 1e7;
int _ThreadCount = 0;
bool _OneWriter = false;
int _Padding = 0;
int _Spacing = 0;
int _Affinity = 0;
public Worker( int threadCount, bool oneWriter, int padding, int spacing, int affinity )
{
_ThreadCount = threadCount;
_OneWriter = oneWriter;
_Padding = padding;
_Spacing = spacing;
_Affinity = affinity;
}
[DllImport( "kernel32.dll" )]
static extern IntPtr GetCurrentThread();
[DllImport( "kernel32.dll" )]
static extern UIntPtr SetThreadAffinityMask( IntPtr hThread, UIntPtr dwThreadAffinityMask );
public TimeSpan Work()
{
var data = new int[ _Padding + ( _ThreadCount * _Spacing ) ];
Array.Clear( data, 0, data.Length );
var iters = ITERS / _ThreadCount;
//var iters = ITERS;
using ( var mre = new ManualResetEvent( false ) )
using ( var countdown = new CountdownEvent( _ThreadCount ) )
{
TimeSpan[] tss = new TimeSpan[ Environment.ProcessorCount ];
for ( int i = 0 ; i < _ThreadCount ; i++ )
{
int iThread = i;
if ( !_OneWriter || iThread == 0 )
{
new Thread( () =>
{
SetThreadAffinityMask( GetCurrentThread(), new UIntPtr( 1u << ( iThread * _Affinity ) ) );
var offset = _Padding + ( iThread * _Spacing );
mre.WaitOne();
for ( int x = 0 ; x < iters ; x++ ) data[ offset ]++;
countdown.Signal();
} ) { IsBackground = true, Priority = ThreadPriority.Highest }.Start();
}
else
{
new Thread( () =>
{
SetThreadAffinityMask( GetCurrentThread(), new UIntPtr( 1u << ( iThread * _Affinity ) ) );
var offset = _Padding + ( iThread * _Spacing );
int dummy = 0;
mre.WaitOne();
for ( int x = 0 ; x < iters ; x++ ) dummy = data[ offset ];
countdown.Signal();
} ) { IsBackground = true, Priority = ThreadPriority.Highest }.Start();
}
}
Thread.Sleep( 100 );
var sw = Stopwatch.StartNew();
mre.Set();
countdown.Wait();
var ts = sw.Elapsed;
Trace.WriteLine( "False : " + data.Sum( i => ( long ) i ).ToString( "N0" ) + " in " + ts.TotalSeconds + " secs" );
return ts;
}
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I discovered C# and .NET 1.0 Beta 1 in late 2000 and loved them immediately.
I have been writing software professionally in C# ever since
In real life, I have spent 3 years travelling abroad,
I have held a UK Private Pilots Licence for 20 years,
and I am a PADI Divemaster.
I now live near idyllic Bournemouth in England.
I can work 'virtually' anywhere!