Как заставить 'gcc' генерировать 'bts' инструкцию для x86-64 из стандарта C?

Вдохновленный недавним вопросом, я хотел бы знать, знает ли кто-либо, как добраться gcc генерировать x86-64 bts инструкция (контроль битов и набор) на платформах Linux x86-64, не обращаясь к встроенному ассемблерному коду или к нестандартному компилятору intrinsics.

Связанные вопросы:

Мобильность более важна для меня, чем bts, таким образом, я не буду использовать и asm директива, и если существует другое решение, я предпочитаю не использовать компилятор instrinsics.

Править: Исходный язык C не поддерживает атомарные операции, таким образом, я особенно не интересуюсь получением атомарного теста-и-набора (даже при том, что это - исходная причина теста-и-набора для существования во-первых). Если я хочу что-то атомарное, я знаю, что у меня нет шанса выполнения его со стандартом C источник: это должно быть внутреннее, библиотечная функция или встроенный ассемблерный код. (Я реализовал атомарные операции в компиляторах, которые поддерживают несколько потоков.)

17
задан Community 23 May 2017 в 12:25
поделиться

3 ответа

Я использую атомные накопители 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 показывает все возможности.

Я понимаю, что это не совсем то, что вы просите, но я нашел эти две веб-страницы очень полезными, когда я искал такие механизмы.

1
ответ дан 30 November 2019 в 14:51
поделиться

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

Вы программируете блокировку данных Datastructures, в которых недостаточны блокировки?

Вы, вероятно, захотите просто идти вперед и использовать нестандартные расширения GCC и / или операционную систему или библиотеку приносят примитивы синхронизации. Я бы поспорил, что есть библиотека, которая может обеспечить тип портативности, которую вы ищете, если вы обеспокоены использовать компилятор внутри. (Хотя действительно, я думаю, что большинство людей просто кусают пулю и используют код, специфичный GCC, когда им это нужно. Не идеально, но стандарты не совсем не поддаются.)

0
ответ дан 30 November 2019 в 14:51
поделиться

Это в первом ответе по первой ссылке - насколько это важно в большой схеме вещей. Единственная часть, когда вы тестируете биты:

  • Низкоуровневые драйверы. Однако, если вы пишете драйвер, вы, вероятно, знаете ASM, он достаточно привязан к системе и, вероятно, большинство задержек приходится на ввод/вывод
  • Тестирование флагов. Обычно это происходит либо при инициализации (только один раз в начале), либо при некоторых общих вычислениях (что занимает гораздо больше времени).

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

К части 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, насколько я помню).
2
ответ дан 30 November 2019 в 14:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: