Как к: Встройте ассемблер в C++ (в соответствии с Visual Studio 2010)

Я пишу критическому по отношению к производительности, перемалыванию чисел проект C++, где 70% времени используются 200 модулями ядра строки.

Я хотел бы оптимизировать базовый встроенный ассемблерный код использования, но я абсолютно плохо знаком с этим. Я действительно, однако, знаю некоторые x86 ассемблеры включая тот, используемый GCC и NASM.

Все я знаю:

Я должен вставить ассемблерные инструкции _asm{} где я хочу, чтобы они были.

Проблема:

  • У меня нет подсказки, где запустить. Что находится, в котором регистре в данный момент играет роль мой встроенный ассемблерный код?
5
задан old_timer 4 September 2018 в 14:56
поделиться

6 ответов

Идите сначала за низко висящими фруктами...

Как уже говорили другие, компилятор Microsoft довольно плохо справляется с оптимизацией. Возможно, вы сможете сэкономить много усилий, просто вложив деньги в достойный компилятор, такой как ICC от Intel, и перекомпилировав код "как есть". Вы можете получить 30-дневную бесплатную ознакомительную лицензию от Intel и опробовать ее.

Также, если у вас есть возможность собрать 64-битный исполняемый файл, то запуск в 64-битном режиме может дать 30% прирост производительности, благодаря увеличению числа доступных регистров на x2.

1
ответ дан 18 December 2019 в 05:36
поделиться

В регистрах ничего нет. при выполнении блока _asm. Вам нужно переместить данные в регистры. Если есть переменная: 'a', тогда вам потребуется

__asm {
  mov eax, [a]
}

. Стоит отметить, что VS2010 поставляется с ассемблером Microsoft. Щелкните проект правой кнопкой мыши, перейдите к правилам сборки и включите правила сборки ассемблера, и среда IDE обработает файлы .asm.

это несколько лучшее решение, поскольку VS2010 поддерживает 32-битные И 64-битные проекты, а ключевое слово __asm ​​НЕ работает в 64-битных сборках. Вы ДОЛЖНЫ использовать внешний ассемблер для 64-битного кода: /

6
ответ дан 18 December 2019 в 05:36
поделиться

Вы можете получить доступ к переменным по их имени и скопировать их в регистры. Вот пример из MSDN:

int power2( int num, int power )
{
   __asm
   {
      mov eax, num    ; Get first argument
      mov ecx, power  ; Get second argument
      shl eax, cl     ; EAX = EAX * ( 2 to the power of CL )
   }
   // Return with result in EAX
}

Использование C или C ++ в блоках ASM также может быть для вас интересным.

13
ответ дан 18 December 2019 в 05:36
поделиться

Компилятор microsoft очень плохо справляется с оптимизацией, когда в дело вступает встроенный ассемблер. Ему приходится резервировать регистры, потому что если вы используете eax, то он не переместит eax в другой свободный регистр, а продолжит использовать eax. Ассемблер GCC гораздо более продвинут в этом отношении.

Чтобы обойти это, компания microsoft начала предлагать intrinsics. Это гораздо лучший способ оптимизации, поскольку он позволяет компилятору работать вместе с вами. Как упомянул Крис, встроенная сборка не работает под x64 с компилятором MS, так что на этой платформе вам действительно лучше использовать intrinsics.

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

.
8
ответ дан 18 December 2019 в 05:36
поделиться

Я предпочитаю писать целые функции на ассемблере, а не использовать встроенную ассемблер. Это позволяет вам заменить функцию языка высокого уровня на функцию сборки во время процесса сборки. Кроме того, вам не нужно беспокоиться об оптимизации компилятора.

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

Если вам нужно вставить встроенную сборку для большой функции, создайте новую функцию для кода, который вам нужно встроить. Снова замените на C ++ или сборку во время сборки.

Это мои предложения, Ваш пробег может варьироваться (YMMV).

3
ответ дан 18 December 2019 в 05:36
поделиться

Мне очень нравится сборка, поэтому я не собираюсь здесь отказываться. Похоже, вы профилировали свой код и нашли «горячую точку», что является правильным способом начать. Я также предполагаю, что 200 рассматриваемых строк не используют много высокоуровневых конструкций, таких как вектор .

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

Все, что было сказано: на вашем месте я бы прошел через рассматриваемый код в отладчике VS, используя представление Disassembly.Если вы чувствуете себя комфортно, читая код по ходу дела, это хороший знак. После этого выполните компиляцию Release (отладка отключает оптимизацию) и сгенерируйте список ASM для этого модуля. Затем , если вы думаете, что видите возможности для улучшения ... у вас есть с чего начать. Ответы других людей связаны с документацией MSDN, которая действительно довольно скудна, но все же является разумным началом.

1
ответ дан 18 December 2019 в 05:36
поделиться
Другие вопросы по тегам:

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