AccessViolationException with Parallel.For() - c#

The code snippet below exhibits a bug I was able to isolate from production code. The program will crash with a System.AccessViolationException.
My system configuration is Visual Studio 2013 on Windows 8.1 x64. To reproduce the bug, follow these steps in Visual Studio:
Create an empty Console Application
Replace the entire contents of Program.cs with the code below
Compile in Release mode, Any CPU
Start without debugging (CTRL + F5)
The program will crash immediately, displaying an error stack trace in the Console window.
I was not able to reduce the code any further, i.e. modifying any portion of the code will make the bug disappear.
Is there any way to tell the root cause of this bug? What would be a good workaround?
using System;
using System.Threading.Tasks;
namespace ParallelBugTest
{
class Program
{
private class Value
{
public double X;
}
private class Aggregator
{
private Value myval = new Value();
public void Add()
{
// use Min() instead of Max() -> bug disappears
myval.X = Math.Max(0, myval.X);
}
}
public static void Main(string[] args)
{
Parallel.For(0, 10000, Process);
}
private static void Process(int k)
{
Value[] V = new Value[10000];
Aggregator aggregator = new Aggregator();
for (int i = 0; i < V.Length; i++)
{
V[i] = new Value();
aggregator.Add();
}
}
}
}

Everything in your code is thread-safe, since there is no shared state between threads (each iteration has its own Aggregator and the array of Values and you're not using any static fields).
Even if your code wasn't thread-safe, it doesn't do anything unsafe (i.e. working directly with memory), which should be the only way to get AccessViolationException.
Because of that, I believe this is a bug in the CLR and you should report it (click on the "submit feedback" link after logging in).

Math.Max is not Thread-Safe. I guess Min is working because it is faster to calculate.
Locking the Max-Call works:
private static Object lockObj = new Object();
private class Value
{
public double X;
}
private class Aggregator
{
private Value myval = new Value();
public void Add()
{
// use Min() instead of Max() -> bug disappears
lock (lockObj)
{
myval.X = Math.Max(0, myval.X);
}
}
}
public static void Main(string[] args)
{
Parallel.For(0, 10000, Process);
}
private static void Process(int k)
{
Value[] V = new Value[10000];
Aggregator aggregator = new Aggregator();
for (int i = 0; i < V.Length; i++)
{
V[i] = new Value();
aggregator.Add();
}
}
Fast and easier way is just to use an ordinary iif:
public void Add()
{
// use Min() instead of Max() -> bug disappears
myval.X = myval.X > 0 ? myval.X : 0;
}

Related

Property of { return 60000 / bpm } always returning 600ms?

I'm trying to build a steady metronome that ticks every beat, but it seems like there is a problem.
How long the metronome waits for each beat is determined by this formula: 60000 / BPM
But, the value seems to return a specific number no matter what value you plug into BPM.
I have a property that returns the value of this formula, along with a bpm integer:
static private int bpm = 125;
static private int BeatLength
{
get
{
return 60000 / bpm;
}
}
static public int beat = 0;
And here is the function that's responsible for the metronome (it runs on a dedicated thread):
public static void RhythmUpdate()
{
lock (threadLock)
{
while (true)
{
Thread.Sleep(BeatLength); // Sleep until the next beat
AddRequest(BeatLength * beat);
beat++;
DefaultSounds.def_CowBell.Play();
OnBeat?.Invoke();
}
}
}
When breakpointing the def_CowBell.Play();, Visual Studio notes that it takes around 600ms to loop. This is how I know the value.
Extra Info:
I'm using OpenGL
Maybe some more if asked...
I appreciate your help in advance.
It turns out that I've been setting BPM on a function, and whenever I made a change to it's initialization it would be overwritten by that new BPM.
public static void StartBeat(int startingBPM)
{
rhythmThread = new Thread(new ThreadStart(RhythmUpdate)); // Initialize new thread
bpm = startingBPM; // < This piece of codde was the source.
rhythmThread.Name = "BeatThread";
rhythmThread.Start(); // Start the thread
}
For now, I'll disable that line of code when testing.

C# MultiThreading: pool of calculators

I want to have a static (global) pool of calculators which are going to be accessed by a lot of different threads.
After some researching I found out that the elements of Arrays are threadsafe.
I thought that it would be good idea to store the diffrent calculators (amount unknown until runtime) in a static array (calculator[] calculators).
How do I ensure that only one calculator is being used by one calculator?
I read the whole msdn documentation so don't post "only" links please.
I have also thought about a bool array "locked" but I can't find a way to implement this threadsafe.
My code so far:
internal static class Calculators
{
private static Semaphore pool;
private static bool[] locked;
private static calcs[] neuralNetworks;
private static Thread[] threads;
internal static Calculators(){
int number = Globals.Number;
pool = new Semaphore(number, number);
locked = new bool[number];
calcs = new calcs[number];
threads = new Thread[number];
for (int index = 0; index < number; index++)
{
// all neuralNetworks are unlocked by default
locked[index] = false;
// generate one network per "countThreads"
calcs[index] = Globals.CalcObj;
// generate one thread for each neural network
threads[index] = new Thread(new ThreadStart());
}
}
private int WhichCalculators()
{
int index;
for (index = 0; index < countThreads; index++)
{
if (locked[index] == false)
{
locked[index] = true;
return index;
}
}
throw new Exception("Calculators was called, but there weren't any networks unused");
}
}
Code Update:
So should it work, if I call "WhichCalculator()" in this method?
private static void doStuff()
{
pool.WaitOne();
Monitor.Enter(thisLock);
try
{
int whichCalculator = WhichCalculator();
locked[whichCalculator] = true;
lock (calculators[whichCalculator])
{
Monitor.Exit(thisLock);
// do stuff
locked[whichCalculator] = false;
}
}
catch
{
Monitor.Exit(thisLock);
}
//Calculate();
pool.Release();
}
Question 2:
Am I right to assume, that the static constructor is going to be executed as soon as (but before) the first time this class or any member of it is going to be accessed?
Yes you have to use lock. But the array and every instance of calculator again.
If you can fill the array before you start the multithreaded section of your code you need not lock the array as well (only reading doesn't make problems due to the static content) but with resizing the array you need to lock every access to it (writing AND reading).
So your code could look like this:
Calculator calc = null;
lock(calculators)
{
calc = calculators[0];
}
lock(calc)
{
// ... do stuff
}
This way the array isn't longer locked then needed and you can lock the calculator itself.
You can lock your array. That would ensure that every array-operation is executed thread-safe.
To ensure, that each object is only used once at a time you can add a flag to it, like calculator.InUse. If you can't add a flag to the class, you can use an extension method.

thread lock object in properties get/set

When using locks, do I need to lock around my get? From my testing I do not need to do so, but I wanted to make sure. Also, how do I format the code I posted so it has the proper schema colors? It is asking me to add more details, but I don't really know what to add- I am moreover asking (from someone more experienced than I) if what I have is correct and will work without throwing cross thread exceptions.
class exam
{
private static readonly exam x = new exam();
private static readonly object lckobj = new object();
private int i;
private int _count;
private exam() { }
public static exam AccessPoint
{
get
{
return x;
}
}
public int myInt
{
get
{
return i;
}
set
{
lock(lckobj)
{
i = value;
}
}
}
public int Count
{
get
{
return _count;
}
set
{
lock(lckobj)
{
_count = value;
}
}
}
}
class myDemo
{
Random r = new Random();
bool b = false;
Thread[] t = new Thread[3];
public myDemo()
{
for(int i=0; i < 3; i++)
{
t[i] = new Thread(new ThreadStart(thread1));
t[i].Start();
}
Thread checks = new Thread(new ThreadStart(checkB));
checks.Start();
}
void checkB()
{
var x = exam.AccessPoint;
while (!b)
{
b = (x.Count >= 10) ? true : false;
Console.WriteLine("\tb:{0}\tCount:{1}", b, x.Count);
Thread.Sleep(100);
}
}
void thread1()
{
var x = exam.AccessPoint;
while (!b)
{
Thread.Sleep(r.Next(500, 1000));
x.myInt = r.Next(1, 10);
x.Count = x.Count + 1;
Console.WriteLine(x.myInt);
}
}
}
Even if you added the lock around the get your code still wouldn't work properly, although there are more possible things that can go wrong if you don't do that.
The following line is problematic in a way that cannot be fixed by locking in Count:
x.Count = x.Count + 1;
Here even if you add locks, it's entirely possible for one thread to read a value, stop before updating, then have another thread read the value, increment the count, and then write it back. That write will be overridden when the first thread continues on. No amount of locking in Count will change that.
Of course, without the lock in Count there is no memory barrier introduced, so reads to that value are allowed to be reading stale values, which can further exacerbate the previous problem.
Reading a value of a variable by multiple threads in the same time is safe.
Writing a value to a variable by multiple threads in the same time is not safe.
Writing a value to a variable by one thread in the same time as one ore more threads are reading from this variable is not safe.
So using the same lock in both setter and getter is required.
Problem described in #Servy answer requires a better solution though. Any flavour of locking mechanism which wraps so called "SELECT FOR UPDATE" (I know this goes for DB but the problem is the same) should be good enough.
You should even reuse the same lock you already have in your code. Make it public since it's readonly and for such situations use it from outside:
lock(exam.lckobj){
exam.myInt = exam.myInt + 1;
}
For integer values use Interlocked.Read and Interlock.Exchange. Very atomic, very thread safe, doesn't carry the weight of a mutex (via lock).

How can a struct with a single object field be faster than a raw object?

I have a struct that holds a single object field to make working with the object easier. I wanted to test the performance (I expected some degradation), but I get very surprising results. The version with the struct actually is faster:
Without box: 8.08 s
With box: 7.76 s
How is this possible?
Below is the complete test code to reproduce the results.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication68
{
partial class Program
{
private const int Iterations = 100000000;
static void Main(string[] args)
{
// Force JIT compilation.
TimeWithoutBox(new MyObject());
TimeWithoutBox(7);
TimeBox(new MyObject());
TimeBox(7);
// The tests.
var withoutBox = new TimeSpan();
var box = new TimeSpan();
for (int i = 0; i < 10; i++)
{
withoutBox += TimeWithoutBox(new MyObject());
withoutBox += TimeWithoutBox(7);
box += TimeBox(new MyObject());
box += TimeBox(7);
}
Console.WriteLine("Without box: " + withoutBox);
Console.WriteLine("With box: " + box);
Console.ReadLine();
}
private static TimeSpan TimeBox(object value)
{
var box = new MyBox(value);
var stopwatch = Stopwatch.StartNew();
for (int i = 0; i < Iterations; i++)
{
TestBox(box);
}
return stopwatch.Elapsed;
}
private static TimeSpan TimeWithoutBox(object value)
{
var stopwatch = Stopwatch.StartNew();
for (int i = 0; i < Iterations; i++)
{
TestWithoutBox(value);
}
return stopwatch.Elapsed;
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void TestBox(MyBox box)
{
if (box.IsDouble)
TakeDouble((double)box.Value);
else if (box.IsObject)
TakeObject((MyObject)box.Value);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void TestWithoutBox(object box)
{
if (box.GetType() == typeof(double))
TakeDouble((double)box);
else if (box.GetType() == typeof(MyObject))
TakeObject((MyObject)box);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void TakeDouble(double value)
{
// Empty method to force consuming the cast.
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void TakeObject(MyObject value)
{
// Empty method to force consuming the cast.
}
}
struct MyBox
{
private readonly object _value;
public object Value
{
get { return _value; }
}
public MyBox(object value)
{
_value = value;
}
public bool IsDouble
{
get { return _value.GetType() == typeof(double); }
}
public bool IsObject
{
get { return _value.GetType() == typeof(MyObject); }
}
}
class MyObject
{
}
}
EDIT:
I've changed the IsDouble and IsObject tests to have the same statements as the other test. I've re-executed the application and the resulting times are exactly the same.
EDIT2:
This code was tested using a Release build compiling at 32-bit without the debugger attached; .NET 4.5 and Visual Studio 2012. Compiling it against 64-bit gives drastically different results; on my machine:
Without box: 8.23 s
With box: 16.99 s
I copied the exact code, ran it Release without debugger (both important!) and on x64. Results:
Without box: 00:00:07.9650541
With box: 00:00:16.0958162
Changing the test to:
[MethodImpl(MethodImplOptions.NoInlining)]
private static void TestBox(MyBox box)
{
if (box.Value.GetType() == typeof(double))
TakeDouble((double)box.Value);
else if (box.Value.GetType() == typeof(MyObject))
TakeObject((MyObject)box.Value);
}
Makes the run times almost equal:
Without box: 00:00:07.9488281
With box: 00:00:08.6084029
Why? Because the JIT decides not to inline IsDouble and manual inlining helps. That is strange because it is such a small function. The call at line 13 is this call.
Now why is there still some performance difference? The .NET JIT is not the best compiler out there... there are probably some instructions a little bit different. You can find out by comparing the disassembly of the two versions. I'll not have time for that because I expect the difference to be quite uninsteresting.
I'd expect a C compiler to get this right. The struct should behave like the single object member that it contains. Small methods should be inlined. This is definitely doable with todays compiler technology. Let's hope that the next generation JIT and NGEN can do this. A new JIT is being developed at the moment (RyuJIT) and they're moving optimizations from the VC backend to NGEN (was recently announced).

Detailed Explanation of Variable Capture in Closures

I've seen countless posts on how variable capture pulls in variables for the creation of the closure, however they all seem to stop short of specific details and call the whole thing "compiler magic".
I'm looking for a clear-cut explanation of:
How local variables are actually captured.
The difference (if any) between capturing value types vs. reference types.
And whether there is any boxing occurring with respect to value types.
My preference would be for an answer in terms of values and pointers (closer to the heart of what happens internally), though I will accept a clear answer involving values and references as well.
Is tricky. Will come onto it in a minute.
There's no difference - in both cases, it's the variable itself which is captured.
Nope, no boxing occurs.
It's probably easiest to demonstrate how the capturing works via an example...
Here's some code using a lambda expression which captures a single variable:
using System;
class Test
{
static void Main()
{
Action action = CreateShowAndIncrementAction();
action();
action();
}
static Action CreateShowAndIncrementAction()
{
Random rng = new Random();
int counter = rng.Next(10);
Console.WriteLine("Initial value for counter: {0}", counter);
return () =>
{
Console.WriteLine(counter);
counter++;
};
}
}
Now here's what the compiler's doing for you - except that it would use "unspeakable" names which couldn't really occur in C#.
using System;
class Test
{
static void Main()
{
Action action = CreateShowAndIncrementAction();
action();
action();
}
static Action CreateShowAndIncrementAction()
{
ActionHelper helper = new ActionHelper();
Random rng = new Random();
helper.counter = rng.Next(10);
Console.WriteLine("Initial value for counter: {0}", helper.counter);
// Converts method group to a delegate, whose target will be a
// reference to the instance of ActionHelper
return helper.DoAction;
}
class ActionHelper
{
// Just for simplicity, make it public. I don't know if the
// C# compiler really does.
public int counter;
public void DoAction()
{
Console.WriteLine(counter);
counter++;
}
}
}
If you capture variables declared in a loop, you'd end up with a new instance of ActionHelper for each iteration of the loop - so you'd effectively capture different "instances" of the variables.
It gets more complicated when you capture variables from different scopes... let me know if you really want that sort of level of detail, or you could just write some code, decompile it in Reflector and follow it through :)
Note how:
There's no boxing involved
There are no pointers involved, or any other unsafe code
EDIT: Here's an example of two delegates sharing a variable. One delegate shows the current value of counter, the other increments it:
using System;
class Program
{
static void Main(string[] args)
{
var tuple = CreateShowAndIncrementActions();
var show = tuple.Item1;
var increment = tuple.Item2;
show(); // Prints 0
show(); // Still prints 0
increment();
show(); // Now prints 1
}
static Tuple<Action, Action> CreateShowAndIncrementActions()
{
int counter = 0;
Action show = () => { Console.WriteLine(counter); };
Action increment = () => { counter++; };
return Tuple.Create(show, increment);
}
}
... and the expansion:
using System;
class Program
{
static void Main(string[] args)
{
var tuple = CreateShowAndIncrementActions();
var show = tuple.Item1;
var increment = tuple.Item2;
show(); // Prints 0
show(); // Still prints 0
increment();
show(); // Now prints 1
}
static Tuple<Action, Action> CreateShowAndIncrementActions()
{
ActionHelper helper = new ActionHelper();
helper.counter = 0;
Action show = helper.Show;
Action increment = helper.Increment;
return Tuple.Create(show, increment);
}
class ActionHelper
{
public int counter;
public void Show()
{
Console.WriteLine(counter);
}
public void Increment()
{
counter++;
}
}
}

Categories

Resources