Функции за извършване на атомарни операции

Има ли функции за извършване на атомарни операции (като увеличаване/намаляване на цяло число) и т.н., поддържани от C Run time библиотека или други помощни библиотеки?

Ако да, какви всички операции могат да бъдат направени атомарни с помощта на такива функции?

Ще бъде ли по-полезно да се използват такива функции от нормалните примитиви за синхронизация като mutex и т.н.?

ОС: Windows, Linux, Solaris & VxWorks


person Jay    schedule 20.02.2010    source източник


Отговори (5)


Преди C11

C библиотеката няма такива.

В Linux gcc предоставя някои -- потърсете __sync_fetch_and_add, __sync_fetch_and_sub и т.н.

В случай на Windows потърсете InterlockedIncrement, InterlockedDecrement``, InterlockedExchange` и т.н. Ако използвате gcc в Windows, предполагам, че той също има същите вградени функции, както в Linux (въпреки че не съм проверил това).

От Solaris ще зависи. Предполага се, че ако използвате gcc, той вероятно (отново) ще има същите вградени функции, както под Linux. Иначе има библиотеки, които се носят наоколо, но нищо наистина стандартизирано.

C11

C11 добави (разумно) пълен набор от атомни операции и атомни типове. Операциите включват неща като atomic_fetch_add и atomic_fetch_sum*_explicit версии на същите, които ви позволяват да посочите модела на подреждане, от който се нуждаете, където тези по подразбиране винаги използват memory_order_seq_cst). Има и fence функции, като atomic_thread_fence и atomic_signal_fence.

Типовете съответстват на всеки от нормалните цели числа - например atomic_int8_t съответстващ на int8_t и atomic_uint_least64_t съответстващ на uint_least64_t. Това са typedef имена, дефинирани в <stdatomic.h>. За да избегнете конфликти с всички съществуващи имена, можете да пропуснете заглавката; самият компилатор използва имена в пространството от имена на имплементатора (напр. _Atomic_uint_least32_t вместо atomic_uint_least32_t).

person Jerry Coffin    schedule 20.02.2010
comment
synch_fetch_and* работи доста добре и преносимо във всичко, което може да хоства gcc, с изключение на ARM. +1 - person Tim Post♦; 21.02.2010

„Полезно“ е ситуационно. Изпълнението винаги зависи от обстоятелствата. Може да очаквате да се случи нещо чудесно, когато изключите мютекс за нещо подобно, но може да не получите никаква полза (ако случаят не е толкова популярен) или да влошите нещата (ако случайно създадете „заключване на въртене“) .

person bmargulies    schedule 20.02.2010

Във всички поддържани платформи можете да използвате атомните операции на GLib . На платформи, които имат вградени атомарни операции (напр. инструкции за асемблиране), glib ще ги използва. На други платформи ще се върне към използването на мютекси.

Мисля, че атомарните операции могат да ви дадат тласък на скоростта, дори ако мутексите са имплементирани с тях. С mutex ще имате поне две атомни операции (заключване и отключване), плюс действителната операция. Ако атомарната операция е налична, това е една операция.

person Michael Ekstrand    schedule 20.02.2010

Не съм сигурен какво имате предвид под C runtime библиотека. Същинският език или стандартната библиотека не ви предоставя никакви средства за това. Ще трябва да използвате специфична за ОС библиотека/API. Също така, не се заблуждавайте от sig_atomic_t -- те не са това, което изглежда на пръв поглед и са полезни само в контекста на манипулатори на сигнали.

person dirkgently    schedule 20.02.2010

В Windows има InterlockedExchange и като. За Linux можете да вземете атомни макроси на glibc - те са преносими (вижте i486 atomic.h ). Не знам решение за другите операционни системи.

По принцип можете да използвате инструкцията xchg на x86 за атомарни операции (работи и на двуядрени процесори).

Що се отнася до втория ви въпрос, не, не мисля, че използването на атомарни операции ще бъде по-бързо от използването на мутекси. Например, библиотеката pthreads вече прилага mutexes с атомарни операции, което е много бързо.

person AndiDog    schedule 20.02.2010