Portable Compare And Swap (атомарные операции) Библиотека C / C ++? - PullRequest
29 голосов
/ 21 июля 2009

Существует ли какая-нибудь небольшая библиотека, которая оборачивает CAS-подобные операции различных процессоров в макросы или функции, переносимые между несколькими компиляторами?

PS. Библиотека atomic.hpp находится внутри пространства имен boost :: interprocess :: detail. Автор отказывается делать ее публичной, ухоженной библиотекой.

Позволяет повторно открыть вопрос и посмотреть, есть ли другие варианты?

Ответы [ 9 ]

30 голосов
/ 20 августа 2009

OPA (Open Portable Atomics) может подойти для ваших нужд. https://trac.mcs.anl.gov/projects/openpa/

Он предоставляет согласованный C API для общих атомарных операций на нескольких платформах под лицензией в стиле MIT. Библиотека небольшая и, безусловно, отвечает вашим требованиям к размеру. Текущий список платформ:

  • Встроенная сборка GCC для процессоров x86, x86_64, ia64, PPC 440 и MIPS 5K. Несколько компиляторов с GCC-совместимым интерфейсом ish также поддерживаются в одних и тех же архитектурах, таких как icc, PGI и IBM xlc.
  • Атомные свойства GCC, поэтому поддерживается большинство установок GCC-4.1 +.
  • Библиотека атомарных операций SUN Solaris.
  • Встроенные функции Windows NT (хотя в настоящее время вам необходимо проделать небольшую дополнительную работу для сборки в Windows).
  • Две псевдоплатформы, эмуляция на основе мьютекса pthread для переносимости на другие неподдерживаемые платформы (при этом жертвуя некоторой производительностью) и «небезопасная» реализация для использования в коде, который условно компилируется в однопоточный код.

Я никогда не использовал его в программе на C ++, хотя он должен работать практически без изменений. Я был бы рад настроить его, если у вас возникнут проблемы (просто напишите opa-discuss@lists.mcs.anl.gov).

25 голосов
/ 21 июля 2009

Библиотека межпроцессного ускорения может быть тем, что вам нужно - включаемый файл Atomic.hpp содержит сравнения и замены для различных платформ и компиляторов.

15 голосов
/ 28 июля 2009

Intel Threading Building Blocks имеет красивый переносной шаблон atomic<T>, который делает то, что вы хотите.Но может ли это быть небольшая библиотека или нет, конечно, можно обсуждать ..

11 голосов
/ 25 июля 2009

Вас могут заинтересовать Атомные операции Глиба функции,

g_atomic_int_compare_and_exchange()

реализует семантику CAS для различных архитектур. Сама реализация относительно проста для понимания и может использоваться автономно без особых усилий, вы можете найти ее на svn.gnome.org/viewvc/ в glib / trunk / glib / gatomic. {C, h} Надеюсь, это поможет!

9 голосов
/ 27 июля 2009

В Mac OS X и Windows есть встроенные функции CompareAndSwap, которые вы должны использовать в любом случае (InterlockedCompareExchange () и OSAtomicCompareAndSwapPtrBarrier () соответственно). Таким образом, будет работать независимо от компиляторов на этих платформах.

В других Unix-системах это немного сложнее, если вы используете GCC 4.1 или новее, вы можете просто использовать его встроенную функцию __sync_val_compare_and_swap (), и многие, хотя и не все компиляторы Unix, поддерживают разумные расширения gcc, так как большая часть кода, созданного в Linux, предполагает они присутствуют.

Так что, если вы хотите обернуть их так, чтобы они работали практически со всеми компиляторами для всех процессоров в OS X и Windows, а также с GCC и некоторыми другими компиляторами на других платформах, вы должны сделать что-то вроде:

boolean CompareAndSwapPointer(volatile * void * ptr,
                                  void * new_value,
                                  void * old_value) {
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
  return OSAtomicCompareAndSwapPtr (old_value, new_value, ptr);
#elif defined(_MSC_VER)
  return InterlockedCompareExchange(ptr, new_value, old_value);
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
  return __sync_val_compare_and_swap(ptr, old_value, new_value);
#else
#  error No implementation
#endif
}

Это не проверено, но я думаю, что это должно быть правильно. Обратите внимание, как все библиотеки ОС принимают аргументы в разных порядках; -)

Очевидно, что вы можете сделать несколько версий для сравнения разного размера, а также поменять их и обернуть в шаблоны, если хотите. API в основном основаны на C и кодируют информацию о типах в функции таким образом, что это немного неприятно для людей, привыкших параметризировать типы с помощью шаблонов.

6 голосов
/ 29 июля 2009

Имеется библиотека проекта atomic_ops от Boehm. Не знаю о лицензии, хотя.

3 голосов
/ 16 августа 2010

Предлагается C ++ 0x-совместимая вспомогательная библиотека Boost: http://www.chaoticmind.net/~hcb/projects/boost.atomic/

Целью этой библиотеки является обеспечить реализацию атомного операции для повышения, основанные на интерфейс, указанный в проекте C ++ 0x стандарт. Стремится сделать переход на std :: atomic easy, как а также предоставление средств для создания кода с помощью этой функции C ++ 0x, скомпилированной на старые системы.

Это, очевидно, еще не является частью Boost, но вы можете проверить ветку обзора здесь:

Boost.Atomic теперь в форме, которую я рассмотреть возможность назвать это релизом. Она имеет поддержка "истинных" атомарных переменных на:

  • gcc / x86, 32-битный (протестировано в Linux, FreeBSD)
  • gcc / x86, 64-разрядная (тестируется в Linux)
  • gcc / powerpc32 (протестировано в Linux, Mac OS X)
  • gcc / powerpc64 (не проверено)
  • универсальный Win32 (протестирован с Visual Studio Express на Win XP)

Для всех остальных это отступает изящно к заблокированной операции. Там правильная быстрая книга документации, в том числе, надеюсь, иллюстративный пример раздела.

2 голосов
/ 29 июля 2009

Автор сказал (по предоставленной вами ссылке): «Я думаю, вы можете безопасно использовать их, пока не появится какая-нибудь официальная библиотека Boost». Откладывать изменение интерфейса до тех пор, пока «атомарные функции не появятся в C ++ 0x».

Что бы вы ни использовали сегодня, вы, вероятно, захотите перейти на новую std:: функциональность, когда она все равно будет доступна.

В целом, поддержка Boost довольно хороша, похоже, она используется в реализации выпущенной библиотеки Boost. Я также испытывал желание использовать эту реализацию несколько раз.

Я бы пошел на это.

0 голосов
/ 30 июля 2009

Вы также можете взглянуть на libsync для вдохновения из http://www.ioremap.net/node/224, который является довольно новым (может быть, слишком новым), но он используется в сети эллиптиков, поэтому он (некоторые?) Тестирует. *

Это также дает вам примитивы более высокого уровня рядом с CAS: RCU (Read Copy Update) для синхронизации без блокировки между потоками.

Но это зависит от того, что вы подразумеваете под «портативным»: он поддерживает архитектуры x86 и PPC, ОС Linux, FreeBSD, OpenBSD, Solaris и MacOSX, но ... нет Windows.

И лицензия GPL, которую вы можете ненавидеть или любить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...