Click here to Skip to main content
16,011,120 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
AnswerRe: Read 3DS file for create character animation - how to ? Pin
MMansonFan2529-Mar-05 23:14
MMansonFan2529-Mar-05 23:14 
GeneralRe: Read 3DS file for create character animation - how to ? Pin
sonla29-Mar-05 23:25
sonla29-Mar-05 23:25 
GeneralInterlocked Functions Pin
Obi Wan 225-Mar-05 15:21
Obi Wan 225-Mar-05 15:21 
GeneralRe: Interlocked Functions Pin
cmk25-Mar-05 16:35
cmk25-Mar-05 16:35 
GeneralRe: Interlocked Functions Pin
Obi Wan 225-Mar-05 17:36
Obi Wan 225-Mar-05 17:36 
GeneralRe: Interlocked Functions Pin
cmk25-Mar-05 19:15
cmk25-Mar-05 19:15 
GeneralRe: Interlocked Functions Pin
Obi Wan 225-Mar-05 22:05
Obi Wan 225-Mar-05 22:05 
GeneralRe: Interlocked Functions Pin
cmk25-Mar-05 23:21
cmk25-Mar-05 23:21 
Obi Wan 2 wrote:
I was hoping to avoid using "InterlockedExchangeAdd(&v, 0)" to get the value of the interlocked variable for performance reasons, but this seems risky.

By using it you will be sure that if another processor/thread has just changed the value that you are getting the new value, not an old cached value. Making the variable volatile _may_ be good enough (more below).

I find it all a little vague in spots as well.
Here's my take on things based on either intel manuals, msdn, ARM, ...:

"Simple reads and writes to properly-aligned 32-bit variables are atomic"

To me, this means (as they also mention), that if one thread is reading a 32-bit value at the same time another is writing to it you won't read a partially written value (i.e. all bytes will be set at once). However, it is unclear to me how this translates to a multi-processor situation where one processor/thread writes to the 32-bit value, and the write is cached, and another processor/thread then tries to read the value. I expect that the second p/t could read an old value from it's cache, or from main memory as the new value is still in the first p/t cache.

A lot of people use volatile to prevent the system from caching values, they use it as if it garanteed atomic behaviour because of this.

The ARM says "there are no implementation-independent semantics for volatile objects; volatile is a hint to the compiler to avoid agressive optimization ..."

From MSDN:
"The system always reads the current value of a volatile object at the point it is requested, even if the previous instruction asked for a value from the same object. Also, the value of the object is written immediately on assignment. One use of the volatile qualifier is to provide access to memory locations used by asynchronous processes such as interrupt handlers."

To me, this implies they create a barrier on read/write access of a volatile - which is likely why people treat it as if it does.

Because the language does not define this as expected behaviour, in my opinion, the only way to write portable/future safe code is to use the interlocked functions. These use the intel asm lock instruction to create a barrier.

The barrier not only flushes the specified variable to main memory, it also fushes any other cached writes for any other variables.

For me the following from MSDN is one of the clearer examples on the use of the interlocked functions:

When a processor writes to a memory location, the value is cached to improve performance. Similarly, the processor attempts to satisfy read requests from the cache to improve performance. Furthermore, processors begin to fetch values from memory before they are requested by the application. This can happen as part of speculative execution or due to cache line issues.<br />
<br />
As a result, multiple processors can have different views of the system memory state because their caches are out of synch. For example, the following code is not safe on a multiprocessor system:<br />

int iValue;
BOOL fValueHasBeenComputed = FALSE;
extern int ComputeValue();

void CacheComputedValue()
{
  if (!fValueHasBeenComputed) 
  {
    iValue = ComputeValue();
    fValueHasBeenComputed = TRUE;
  }
}

BOOL FetchComputedValue(int *piResult)
{
  if (fValueHasBeenComputed) 
  {
    *piResult = iValue;
    return TRUE;
  } 
  else 
    return FALSE;
}

There is a race condition in this code on multiprocessor systems because the processor that executes CacheComputedValue the first time may write fValueHasBeenComputed to main memory before writing iValue to main memory. Consequently, a second processor executing FetchComputedValue at the same time reads fValueHasBeenComputed as TRUE, because the new value of iValue is still in the first processor's cache.<br />
<br />
Processors can be instructed to force their memory caches to agree with main memory with special instructions. Such instructions ensure that previous read and write requests have completed and are made visible to other processors, and to ensure that that no subsequent read or write requests have started. Examples are:<br />
<br />
Functions which enter or leave critical sections. <br />
Functions which signal synchronization objects. <br />
Wait functions. <br />
Interlocked functions <br />
Consequently, the multiprocessor race condition above can be repaired as follows:

void CacheComputedValue()
{
  if (!fValueHasBeenComputed) {
    iValue = ComputeValue();
    InterlockedExchange((LONG*)&fValueHasBeenComputed, TRUE);
  }
}

The InterlockedExchange function ensures that the value of iValue is updated for all processors before the value of fValueHasBeenComputed is set to TRUE.



...cmk

Save the whales - collect the whole set
GeneralRe: Interlocked Functions Pin
Obi Wan 226-Mar-05 1:57
Obi Wan 226-Mar-05 1:57 
GeneralRe: Interlocked Functions Pin
Obi Wan 230-Oct-05 9:24
Obi Wan 230-Oct-05 9:24 
GeneralMemory Limits Pin
Obi Wan 225-Mar-05 14:45
Obi Wan 225-Mar-05 14:45 
GeneralRe: Memory Limits Pin
David Crow25-Mar-05 16:02
David Crow25-Mar-05 16:02 
GeneralRe: Memory Limits Pin
Obi Wan 225-Mar-05 17:21
Obi Wan 225-Mar-05 17:21 
GeneralRestart the process Pin
mpapeo25-Mar-05 13:38
mpapeo25-Mar-05 13:38 
GeneralRe: Restart the process Pin
Anand for every one25-Mar-05 21:41
Anand for every one25-Mar-05 21:41 
GeneralRe: Restart the process Pin
mpapeo26-Mar-05 9:00
mpapeo26-Mar-05 9:00 
GeneralActiveX in C++ Pin
j1webb25-Mar-05 12:36
j1webb25-Mar-05 12:36 
General&lt;&lt;NEWB-Troubles with stacks Pin
rdt25325-Mar-05 11:48
rdt25325-Mar-05 11:48 
GeneralRe: &lt;&lt;NEWB-Troubles with stacks Pin
Paul M Watt25-Mar-05 12:56
mentorPaul M Watt25-Mar-05 12:56 
GeneralRe: <<NEWB-Troubles with stacks Pin
FlyingTinman25-Mar-05 13:05
FlyingTinman25-Mar-05 13:05 
GeneralRe: &lt;&lt;NEWB-Troubles with stacks Pin
rdt25325-Mar-05 15:42
rdt25325-Mar-05 15:42 
GeneralRe: &lt;&lt;NEWB-Troubles with stacks Pin
David Crow25-Mar-05 16:03
David Crow25-Mar-05 16:03 
GeneralRe: &lt;&lt;NEWB-Troubles with stacks Pin
rdt25325-Mar-05 16:11
rdt25325-Mar-05 16:11 
GeneralRe: &lt;&lt;NEWB-Troubles with stacks Pin
David Crow26-Mar-05 7:07
David Crow26-Mar-05 7:07 
GeneralAccessing and displaying data of worker thread function Pin
Member 153706925-Mar-05 11:11
Member 153706925-Mar-05 11:11 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.