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