Как: встроенный ассемблер в C ++ (под Visual Studio 2010) - PullRequest
5 голосов
/ 15 мая 2010

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

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

Все, что я знаю:

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

Проблема:

  • Понятия не имею, с чего начать. Что находится в каком регистре в момент, когда моя встроенная сборка вступает в игру?

Ответы [ 6 ]

13 голосов
/ 15 мая 2010

Вы можете получить доступ к переменным по их имени и скопировать их в регистры. Вот пример из 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 также может быть вам интересно.

8 голосов
/ 15 мая 2010

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

Чтобы обойти это Microsoft начал предлагать встроенных . Это гораздо лучший способ выполнить оптимизацию, поскольку он позволяет компилятору работать с вами. Как упомянул Крис, встроенная сборка не работает под x64 с компилятором MS, поэтому на этой платформе вам ДЕЙСТВИТЕЛЬНО лучше использовать встроенные функции.

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

6 голосов
/ 15 мая 2010

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

__asm {
  mov eax, [a]
}

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

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

3 голосов
/ 16 мая 2010

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

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

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

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

1 голос
/ 16 мая 2010

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

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

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

1 голос
/ 15 мая 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...