Можно ли это сделать атомарно?
void load_and_store(int* dst, int* src) {
int data = *src;
*dst = data;
}
Если атомный магазин должен быть сделан с XCHG [addr], EAX
Я должен был бы загрузить данные в EAX
первый. Тогда загрузка и хранение не являются атомарными.
GCC атомное расширение имеет void __atomic_store (type *ptr, type *val, int memmodel)
что выглядит как возможность загружать и хранить атомарно.
Я не верю, что на x86 существует какая-либо инструкция, которая атомарно выполняет загрузку и сохранение по разным адресам. (Я не уверен насчет других архитектур, но я сомневаюсь, что есть очень много, если таковые имеются, которые делают. Это не имеет никакой полезной ценности и будет дорого.)
x86 (и x86_64) имеют ряд инструкций, которые могут быть сделаны для выполнения атомарных операций чтения-изменения-записи но только в одну ячейку памяти. Например BTS
делает тест и набор. XCHG
обменивает значение в регистре со значением в ячейке памяти. XADD
делает атомный прирост. CMPXCHG
делает сравнение и обмен. По умолчанию они не являются атомарными, но их можно сделать атомными, добавив LOCK
префикс к инструкции по сборке.
Гну __atomic_store(type *ptr, type *val, int memmodel)
не делает то, что вы думаете, что делает. Увидеть http://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html. Что он делает, это загрузить val
в регистр (или что-то (это на самом деле не определено, что он делает с val)), а затем атомарно сохраняет значение в ячейке памяти, заданной ptr
,
На х86 выровненный нагрузки и хранилища (для значений 32 бит и менее) по умолчанию являются атомарными.
Но вы не должны использовать встроенные функции gnu, если не обязаны. Вместо этого используйте --std=c++11
флаг, а затем использовать C ++ atomics
.
Других решений пока нет …