Le 5 oct. 2009 à 10:26, Thiago Macieira a écrit :

> Em Domingo 04 Outubro 2009, às 10:28:46, você escreveu:
>> Le 4 oct. 09 à 09:35, Thiago Macieira a écrit :
>>> Em Sábado 3. Outubro 2009, às 17.13.48, você escreveu:
>>>> Can I use QAtomicInt as "an Int with basic operations being  
>>>> atomic":
>>>> like getting, setting its value. Returning it from a function.
>>>> If not, when and how can I use it.
>>>
>>> int is already atomic in those operations.
>>>
>>> QAtomicInt introduces new atomic operations: fetch-and-add, test- 
>>> and-
>>> set and
>>> fetch-and-set. As for the memory ordering semantics, you had better
>>> read a
>>> book.
>>
>> But native set and get operations do not ensure cache consistency
>> among your processors (you are just guaranteed that, as long as your
>> data are correctly aligned, you'll never read a partial result from
>> another thread) while atomic fetch-and-add, test-and-set and fetch- 
>> and-
>> set use a memory barrier (AFAIK, atomic integers are useless without
>> memory barrier).
>
> Hmm... you're asking for loadAcquire and storeRelease functions to  
> be added.

Hum, in fact, my point was not about acquire/release semantics (but  
your post on the blog is great).

My point is that, even if native set/get are atomic operations (you  
never see the intermediate results), they do not provide the same  
semantic as fetch-and-set, test-and-set, fetch-and-add... even on  
volatile variables, native get/set ensure the data is not kept in a  
register, nothing more.

On amd64 :
int testVolatile(volatile int* i) {
   if (*i == 0) {
     return 0;
   } else if (*i == 1) {
     return 1;
   }
   return -1;
}

produces following assembly code:
testVolatile:
.LFB2:
   movl  (%rdi), %eax
   xorl  %edx, %edx
   testl %eax, %eax
   jne .L9
.L4:
   movl  %edx, %eax
   ret
.L9:
   movl  (%rdi), %eax
   xorl  %edx, %edx
   cmpl  $1, %eax
   sete  %dl
   leal  -1(%rdx,%rdx), %edx
   jmp .L4

(The same without volatile just kill the second  movl  (%rdi), %eax,  
as expected)

So, this produce "normal" mov instructions, that fetches data from the  
cache if available. But on a modern computer, with several cores (or  
several processors), you have a cache per processor or at least per  
group of cores (on a core2quad, you have 2 caches, one per pair of  
core).

On the contrary, fetch-and-set and friends issue a LOCK# signal that  
ensure cache consistency between your processors (see Intel  
Architectures Software Developer’s Manual, Volume 3A, Section 8.1.4  
for details). So even if get/set are atomic operation, they do not  
provide the same thread-safety as provided by lock+xadd, lock+cmpxchg  
or xchg since they don't ensure we're not fetching the data from an  
outdated cache line.
-- 
Florent Bruneau



_______________________________________________
Qt4-preview-feedback mailing list
[email protected]
http://lists.trolltech.com/mailman/listinfo/qt4-preview-feedback

Reply via email to