Re: Memory acces completely optimized away
gast128@hotmail.com wrote:
When I wrote a little test application, I noticed that the memory
access was completely removed in release builds (both vstudio 2003 as
2008):
void TestIntlIppiImplFlood(/*volatile*/ long* pContinue)
{
while (*pContinue)
{ }
}
In dissambly:
void TestIntlIppiImplFlood(/*volatile*/ long* pContinue)
{
00981270 mov eax,dword ptr [esp+4]
00981274 mov eax,dword ptr [eax]
while (*pContinue)
00981276 test eax,eax
00981278 jne TestIntlIppiImplFlood+6 (981276h)
{
}
}
One can notice that only the value of *pContinue is stored in eax, and
this is tested. Even if pContinue is modified in another thread, the
function never ends.
You should use Interlocked* family of functions to access variables =
shared between threads. Alternatively, use proper synchronization =
primitives such as critical sections.
This is quite an optimization, but I think it is too agressive. Ofc I
can use volatile for the address, but in effect this means that every
shared variable over threads must get the volatile keyword. I am aware
that one should use boost::mutex or other stuff to prevent data race
conditions, but this was just a simple test in which the variable was
atomicly changed (thru InterlockedIncrement) in one thread and read in
another thread.
Synchronizing access to shared data only works when all threads do it. =
It's pointless to do it in some places but not in others. Use =
InterlockedCompareExchange to atomically read your variable - like this:
while (InterlockedCompareExchange(pContinue, 0, 0)) {...}
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not =
necessarily a good idea. It is hard to be sure where they are going to =
land, and it could be dangerous sitting under them as they fly overhead. =
-- RFC 1925