Переносимая библиотека сравнения и подкачки (атомарные операции) C / C ++?

StackOverflow https://stackoverflow.com/questions/1158374

Вопрос

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

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

Давайте еще раз откроем вопрос и посмотрим, есть ли какие-либо другие варианты?

Это было полезно?

Решение

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

Другие советы

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

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

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

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

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

Возможно, вас заинтересует Атомарные операции Glib функции,

g_atomic_int_compare_and_exchange()

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

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

В других Unix-версиях это немного сложнее, если вы используете GCC 4.1 или новее, вы можете просто использовать его встроенные __sync_val_compare_и_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 и кодируют информацию о типе в функции таким образом, что это довольно неприятно для людей, привыкших параметризовать типы с помощью шаблонов.

Там есть библиотека самого атомарный_ops проект Бема.Хотя не знаю насчет лицензии.

Существует предлагаемая библиотека Boost atomics, совместимая с C ++ 0x: http://www.chaoticmind.net /~гхб/проекты/boost.atomic/

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

Очевидно, что это еще не часть Boost, но вы можете ознакомиться с обзорной веткой здесь: http://lists.boost.org/Archives/boost/2009/12/160195.php

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)

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top