Функции для выполнения атомарных операций

Существуют ли функции для выполнения атомарных операций (например, увеличение / уменьшение целого числа) и т. Д., Поддерживаемые C Run time library или любыми другими служебными библиотеками?

Если да, то что все операции можно сделать атомарными, используя такие функции?

Будет ли выгоднее использовать такие функции, чем обычные примитивы синхронизации, такие как мьютекс и т. Д.?

ОС: Windows, Linux, Solaris и VxWorks

5 ответов

Решение

До C11

Библиотека C не имеет никакой.

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

В случае Windows ищите InterlockedIncrement, InterlockedDecrement``,InterlockedExchange` и так далее. Если вы используете gcc в Windows, я предполагаю, что он также имеет те же встроенные функции, что и в Linux (хотя я этого не проверял).

От Соляриса это будет зависеть. Предположительно, если вы используете 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).

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

Я думаю, что атомарные операции могут дать вам ускорение, даже если мьютексы реализованы с их использованием. С мьютексом у вас будет как минимум две атомные операции (блокировка и разблокировка) плюс фактическая операция. Если атомная операция доступна, это одна операция.

"Выгодно" является ситуативным. Всегда производительность зависит от обстоятельств. Вы можете ожидать, что что-то чудесное произойдет, когда вы отключите мьютекс для чего-то подобного, но вы можете не получить никакой выгоды (если это не так популярно в случае) или ухудшить ситуацию (если вы случайно создадите "спин-блокировку"),

Не уверен, что вы подразумеваете под библиотекой времени выполнения C. Собственно язык или стандартная библиотека не предоставляют никаких средств для этого. Вы должны будете использовать специфическую для ОС библиотеку /API. Кроме того, не обманывайте себя sig_atomic_t - они не являются тем, чем кажется на первый взгляд, и полезны только в контексте обработчиков сигналов.

На Windows есть InterlockedExchange и тому подобное. Для Linux вы можете использовать атомарные макросы glibc - они переносимы (см. I486 atomic.h). Я не знаю решения для других операционных систем.

В общем, вы можете использовать xchg инструкция на x86 для атомарных операций (работает также на двухъядерных процессорах).

Что касается вашего второго вопроса, нет, я не думаю, что использование атомарных операций будет быстрее, чем использование мьютексов. Например, библиотека pthreads уже реализует мьютексы с атомарными операциями, что очень быстро.

Другие вопросы по тегам