Click here to Skip to main content
15,879,474 members
Please Sign up or sign in to vote.
5.00/5 (3 votes)
Hi, I am having a bizarre problem where I am reading a non-null variable as null when I pass it to another thread. I can make it volatile, use locks or thread barriers, but sometime it is read as null.
If before reading such variable I write 3mb of data into an array, then it reads fine. So I am sure it is a cache problem, but I do not know how to flush the cache directly.
Posted

There is no way to do this in C# code. You'd have to write up a small block of code either in Intel Assembler or inside an ASM block in C, compiling to a .DLL, then call that from your C# code.

More on the instructions can be found at here[^].
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 1-Apr-11 14:08pm    
This is correct, but it should not affect a bug-free code, I think. CPU cache is something designed to work transparently. My 5 anyway.

Dave, Paulo,

Relax, its' 1st of April today; so anything can happen!
Better see my 1st of April post.
Here (with my "Answer", of course):
http://www.codeproject.com/Answers/175616/WARNING-Black-Line-of-Death-in-windows-phone-7.aspx

Cheers! :-) :-)
--SA
Updated answer;

Sorry, I misunderstand your question. For flushing the cpu cache, I am afraid there is nothing to you can do in c#. But
* Thrash the cache by doing some very large memory operations between iterations of the code you're benchmarking. Maybe execution of huge line of codes
 
Share this answer
 
v3
Comments
Paulo Zemek 1-Apr-11 13:30pm    
I am talking about CPU cache, not about the Cache object.
I had a similar problem where anonymous delegates on the threadpool were running with old instances of a private field. It was quite frustrating to diagnose.

In my case, because it was an NUnit test, I decided to hold a weak reference to the field in the [TearDown] method and just wait for it to be garbage collected. I think forcing a GC somehow makes sure that all cores read the correct value for a field; because it would be very bad for the runtime if a core read a GCed value after a full GC.

Obviously, this approach won't work in production code or high performance code. If I had the same problem in production code, what I would do is create a new object for each thread. I'd ensure that the delegate starting the thread and the field were in the same object, thus ensuring that the core HAS to pull the new object from system RAM each time.

Are you running under VMware Fusion by any chance? I'm wondering if my problem is a symptom of a bug in the VM, as opposed to a real-world problem that needs to be fixed.
 
Share this answer
 
Comments
Paulo Zemek 26-Dec-11 18:42pm    
In my case it was a recently installed computer... it has a real hardware problem, but I only noticed it in my application.
I don't even know its real cause... but a new computer was brought and solved everything.
If you get wrong values, it tells me your thread synchronization code is wrong. There is no need to worry about caches, what you need to do is make appropriate use of the volatile keyword and/or apply proper thread synchronization primitives.

:)
 
Share this answer
 
Comments
Paulo Zemek 26-Dec-11 18:40pm    
This is an old question... but the problem was a hardware one that appeared very often in my code... already solved.
GWBas1c 27-Dec-11 16:35pm    
In my case I was performing volatile reads from a field, yet still getting old references. The code queueing an item in the threadpool was part of the loop assigning new values to the field, thus I couldn't imagine a way that the item on the threadpool could get an old version of the object unless it was reading it from a stale cache. Volatile didn't work; nor did copying the field's value into a closure for the threadpool anonymous delegate; nor did passing the correct value of the field as the "state" object to QueueUserWorkItem.

The only thing that worked was waiting for the old object to be garbage collected. Of course, if this was something other then an NUnit test, I would have taken a much different approach.

I do suspect VMware fusion, because I know that VM authors sometimes put in "optimizations" that break constrains that developers rely on. It could also be a compiler issue, debugger issue, ect, ect. What I do know, however, is that the "volatile" keyword was not being used as documented.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900