Вдохновленный недавним вопросом, я хотел бы знать, знает ли кто-либо, как добраться gcc
генерировать x86-64 bts
инструкция (контроль битов и набор) на платформах Linux x86-64, не обращаясь к встроенному ассемблерному коду или к нестандартному компилятору intrinsics.
Связанные вопросы:
Мобильность более важна для меня, чем bts
, таким образом, я не буду использовать и asm
директива, и если существует другое решение, я предпочитаю не использовать компилятор instrinsics.
Править: Исходный язык C не поддерживает атомарные операции, таким образом, я особенно не интересуюсь получением атомарного теста-и-набора (даже при том, что это - исходная причина теста-и-набора для существования во-первых). Если я хочу что-то атомарное, я знаю, что у меня нет шанса выполнения его со стандартом C источник: это должно быть внутреннее, библиотечная функция или встроенный ассемблерный код. (Я реализовал атомарные операции в компиляторах, которые поддерживают несколько потоков.)
Я использую атомные накопители GCC, такие как __ sync_lock_test_and_set
( http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/atomic -Builtins.html ). Изменение -March
флаг будет напрямую влиять на то, что генерируется. Я использую его с I686
прямо сейчас, но http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/i386-and-x86_002d64-opptions.html# i386-and-and-x86_002d64-options показывает все возможности.
Я понимаю, что это не совсем то, что вы просите, но я нашел эти две веб-страницы очень полезными, когда я искал такие механизмы.
Я полагаю, что (но не уверен), что ни стандарты C ++ или C не имеют никаких механизмов для этих типов механизмов синхронизации. Поддержка механизмов синхронизации более высокого уровня находятся в различных состояниях стандартизации, но я даже не думаю, что один из них позволит вам получить доступ к типу примитивных вы после.
Вы программируете блокировку данных Datastructures, в которых недостаточны блокировки?
Вы, вероятно, захотите просто идти вперед и использовать нестандартные расширения GCC и / или операционную систему или библиотеку приносят примитивы синхронизации. Я бы поспорил, что есть библиотека, которая может обеспечить тип портативности, которую вы ищете, если вы обеспокоены использовать компилятор внутри. (Хотя действительно, я думаю, что большинство людей просто кусают пулю и используют код, специфичный GCC, когда им это нужно. Не идеально, но стандарты не совсем не поддаются.)
Это в первом ответе по первой ссылке - насколько это важно в большой схеме вещей. Единственная часть, когда вы тестируете биты:
Общее влияние на производительность приложений и макробенчмарков, скорее всего, будет минимальным, даже если микробенчмарки покажут улучшение.
К части Edit - использование bts
само по себе не гарантирует атомарность операции. Оно гарантирует лишь то, что она будет атомарной на данном ядре (так же, как или
, выполняемые на памяти). На многопроцессорных (редкость) или многоядерных (очень распространено) устройствах вам все равно придется синхронизироваться с другими процессорами.
Поскольку синхронизация стоит гораздо дороже, я считаю, что разница между:
asm("lock bts %0, %1" : "+m" (*array) : "r" (bit));
и
asm("lock or %0, %1" : "+m" (*array) : "r" (1 << bit));
минимальна. А вторая форма:
__sync_fetch_and_or (array, 1 << bit)
форма (работает на gcc и intel compiler, насколько я помню).