Atomic Exchange Implementation
-
- Member
- Posts: 524
- Joined: Sun Nov 09, 2008 2:55 am
- Location: Pennsylvania, USA
Atomic Exchange Implementation
I'm working on an atomic exchange operation without locks, semaphores, etc.
From looking on the internet I'm fairly certain this is possible. However, I can't figure out how to do it properly.
My function is in the form atomicexchange(int* a,int* b); Any ideas?
From looking on the internet I'm fairly certain this is possible. However, I can't figure out how to do it properly.
My function is in the form atomicexchange(int* a,int* b); Any ideas?
-
- Member
- Posts: 524
- Joined: Sun Nov 09, 2008 2:55 am
- Location: Pennsylvania, USA
Re: Atomic Exchange Implementation
Okay, i think i have something that might work.
It seems to work okay. Any problems?
Code: Select all
SyncExchangeQ:
.start:
mov rax, qword [rdi]
mov rdx, qword [rsi]
.tryagain_rdi:
lock cmpxchg qword [rdi], rdx
jnz .tryagain_rdi
xchg rax, rdx
.tryagain_rsi
lock cmpxchg qword [rsi], rdx
jnz .tryagain_rsi
ret
- Love4Boobies
- Member
- Posts: 2111
- Joined: Fri Mar 07, 2008 5:36 pm
- Location: Bucharest, Romania
Re: Atomic Exchange Implementation
So what's wrong with:
Code: Select all
mov rax,qword [rdi]
mov rdx,qword [rsi]
mov [rdi],rdx
mov [rsi],rax
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
[ Project UDI ]
Re: Atomic Exchange Implementation
Hi,
Also, another CPU can modify the values, causing your code to corrupt the value that's moved to [rsi]. For example:
AFAIK the only way this can be done is:
Of course this has limitations - the qwords need to be next to each other in memory, and CMPXCHG16B isn't supported on some 64-bit CPUs. If the values were 32-bit then you could use CMPXCHG8B instead (which should be supported on all 64-bit CPUs).
Cheers,
Brendan
Sure - another CPU can read both values after you've written the new value to [rdi] but before you've written the new value to [rsi] (which means it's not atomic). For example:JohnnyTheDon wrote:Okay, i think i have something that might work.
It seems to work okay. Any problems?
Code: Select all
SyncExchangeQ:
.start:
mov rax, qword [rdi]
mov rdx, qword [rsi]
.tryagain_rdi:
lock cmpxchg qword [rdi], rdx
jnz .tryagain_rdi
xchg rax, rdx
;*** ANOTHER CPU READS BOTH [RDI] and [RSI] HERE ***
.tryagain_rsi
lock cmpxchg qword [rsi], rdx
jnz .tryagain_rsi
ret
Code: Select all
SyncExchangeQ:
.start:
mov rax, qword [rdi]
mov rdx, qword [rsi]
.tryagain_rdi:
lock cmpxchg qword [rdi], rdx
jnz .tryagain_rdi
xchg rax, rdx
;*** ANOTHER CPU MODIFIES BOTH [RDI] and [RSI] HERE ***
.tryagain_rsi
lock cmpxchg qword [rsi], rdx
jnz .tryagain_rsi
ret
AFAIK the only way this can be done is:
Code: Select all
.retry:
mov rax, [rdi]
mov rdx, [rdi+8]
mov rcx, rax
mov rbx, rdx
lock cmpxchg16b [rdi]
jne .retry
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: Atomic Exchange Implementation
Hi,
Cheers,
Brendan
That's not atomic at all:Love4Boobies wrote:So what's wrong with:
Code: Select all
mov rax,qword [rdi]
;** Other CPUs modify [rsi] and [rdi] here ***
mov rdx,qword [rsi]
;** Other CPUs modify [rsi] and [rdi] here ***
mov [rdi],rdx
;** Other CPUs read or modify [rsi] and [rdi] here ***
mov [rsi],rax
;** Values at [rsi] and [rdi] not guaranteed to be in sync anymore ***
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
-
- Member
- Posts: 524
- Joined: Sun Nov 09, 2008 2:55 am
- Location: Pennsylvania, USA
Re: Atomic Exchange Implementation
Okay, that makes sense. I just realized there isn't much of a use for this in my code, I can get away with
And just use a normal xchg instruction.
Code: Select all
int atomicExchange(int* a, int b)
- Love4Boobies
- Member
- Posts: 2111
- Joined: Fri Mar 07, 2008 5:36 pm
- Location: Bucharest, Romania
Re: Atomic Exchange Implementation
I'm sorry, I was thinking of atomic in the sense of threads, not CPUs. Perhaps I should have noticed the LOCK prefix. Anyway, I've never actually written any code for multiple CPUs, nor HT/SMT and I had no clue that one CPU could modify the register of another. I thought that each had their own set of register and just had access to the same memory (at least for SMP).
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
[ Project UDI ]
-
- Member
- Posts: 524
- Joined: Sun Nov 09, 2008 2:55 am
- Location: Pennsylvania, USA
Re: Atomic Exchange Implementation
They do have their own registers and access to the same memory. The problem isn't that registers are getting edited, the problem is that the memory values are getting edited.I thought that each had their own set of register and just had access to the same memory (at least for SMP).