gcc atomics: sync_and_and_fetch - зачем там цикл?
"lock and" оcтавит результат в памяти, и атомарно его оттуда уже не вытащить.
И да, для читабельности надо компилировать с оптимизацией:
0: 48 8b 07 mov (%rdi%rax
3: 48 89 c2 mov %rax,%rdx
6: 48 21 f2 and %rsi,%rdx
9: f0 48 0f b1 17 lock cmpxchg %rdx%rdi)
e: 75 f3 jne 3 <_Z4saafPVll+0x3>
10: 48 89 d0 mov %rdx,%rax
13: c3 retq
А как без цикла?Для иллюстрации:
"lock and" оcтавит результат в памяти, и атомарно его оттуда уже не вытащить.
void saaf(volatile long *x, long v)
{
__sync_and_and_fetch(x,v);
}
saaf:
lock andq %rsi, (%rdi)
ret
А зачем он у меня две лишние инструкции mov rax -> rdx -> rax нахреначил?
В адресах 3 и 6 в %rax лежит старое значение (%rdi а в %rdx вычисляется новое.
После cmpxhg выолняется одно из двух:
1) значение в (%rdi) поменялось пока мы вычисляли %rdx -> загружаем в %rax новое значение и retry
2) значение в (%rdi) не поменялось -> пишем туда значение из %rdx и выходим из цикла
теперь нам нужно вернуть новое значение, которое в %rdx -> записываем его в %rax.
Поскольку cmpxchg работает чисто с rax и возвращаемое значение тоже, то никак mov не сэкономить.
Спасибо всем, разобрался
Оставить комментарий
yolki
для 64-битного линукса оно сгенерило такой код:исходник:
нафига там цикл?