Как получить `gcc` для генерации инструкции` bts` для x86-64 из стандартного C?
Вдохновленный недавним вопросом , я хотел бы знать, знает ли кто, как получить gcc
для генерации инструкции x86-64 bts
(бит тест и набор) на платформах x86-64 Linux, не прибегая к встроенной сборке или к нестандартным встроенным компиляторам.
Похожие вопросы:
Переносимость для меня важнее, чем bts
, поэтому я не буду использовать директиву и asm
, а если есть другое решение, я предпочитаю не использовать инкрементные установки компилятора.
EDIT: исходный язык C не поддерживает атомарные операции, поэтому я не особо заинтересован в получении атомарного тестирования и настройки (хотя исходная причина тестового набора чтобы существовать в первую очередь). Если я хочу что-то атомарное, я знаю, что у меня нет шансов сделать это со стандартным источником C: это должна быть внутренняя, библиотечная функция или встроенная сборка. (Я реализовал атомарные операции в компиляторах, которые поддерживают несколько потоков.)
Ответы
Ответ 1
В первом ответе за первое звено - насколько это важно в великой схеме вещей. Единственная часть, когда вы тестируете биты:
- Низкоуровневые драйверы. Однако, если вы пишете один, вы, вероятно, знаете ASM, он достаточно привязан к системе и, вероятно, большинство задержек происходит на вводе/выводе
- Тестирование флажков. Обычно это либо при инициализации (один раз только в начале), либо при некоторых общих вычислениях (что занимает гораздо больше времени).
Общее влияние на производительность приложений и макропринципов, вероятно, будет минимальным, даже если микробенчмарки показывают улучшение.
Для части Редактировать - только с помощью bts
не гарантирует атома операции. Все это гарантирует, что он будет атомарным на этом ядре (так что or
выполняется в памяти). На многопроцессорных устройствах (необычных) или многоядерных устройствах (очень распространенных) вам все равно придется синхронизировать с другими процессорами.
Поскольку синхронизация намного дороже, я считаю, что разница между:
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, насколько я помню).
Ответ 2
Я использую встроенные ядра 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-Options.html#i386-and-x86_002d64-Options показывает все возможности.
Я понимаю, что это не то, о чем вы просите, но я нашел эти две веб-страницы очень полезными, когда я искал такие механизмы.
Ответ 3
Я считаю (но не уверен), что ни стандарты С++, ни C не имеют механизмов для этих типов механизмов синхронизации. Поддержка механизмов синхронизации более высокого уровня находится в разных состояниях стандартизации, но я даже не думаю, что один из них позволит вам получить доступ к типу примитива, который вы после.
Вы программируете блокирующие данные, где блокировки недостаточны?
Вероятно, вы захотите просто использовать gcc нестандартные расширения и/или операционную систему или библиотеку, обеспечивающие примитивы синхронизации. Я бы поставил там библиотеку, которая могла бы обеспечить тип переносимости, который вы ищете, если вы обеспокоены использованием встроенных функций компилятора. (Хотя действительно, я думаю, что большинство людей просто кусают пулю и используют код, специфичный для gcc, когда они в ней нуждаются. Не идеальны, но стандарты на самом деле не поддерживаются.)