Оптимизатор Intel C ++ удаляет код masm

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

#include <iostream>
#include <time.h>

using namespace std;

extern "C" {
int Add(int a, int b);
}int main(int argc, char * argv[]){
int startingTime = clock();
for (int i = 0; i < 100; i++)
{
cout << "normal: " << i << endl;
cout << 1000 + 1000 << endl;
}
int timeTaken1 = clock() - startingTime;

startingTime = clock();
for (int i = 0; i < 100; i++){
cout << "assem" << i << endl;
cout << Add(2000, 2000) << endl;
}
int timeTaken2 = clock() - startingTime;

cout << "Time taken under normal addition: " << timeTaken1 << endl;
cout << "Time taken under assembly addition: " << timeTaken2 << endl;

cin.get();
return 0;
}

И следующий код masm:

.model flat
.386

.code

public _Add

_Add PROC
push ebp            ;
mov ebp, esp        ;
mov eax, [ebp + 8]  ;
mov ebx, [ebp + 12] ;
add eax, ebx        ;
leave               ; cleanup
ret                 ;_Add endp
end

Я использую Visual Studio для компиляции, используя плагин Intel Composer. Когда я запускаю это в режиме отладки, он работает отлично — я вижу «нормальный 99» и «ассемблер 99» вместе с соответствующим номером. Когда я запускаю это с / 0d, указанным для компилятора, то он также работает нормально. Однако, когда указаны / 02, / 0x или / 03, он показывает только нормальный (i + j) цикл сложения и первое значение сложения ассемблера, то есть показаны только сборки 0 и 4000.

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

Спасибо
SbSpider

РЕДАКТИРОВАТЬ:
Я знаю, что уже поздно, но спасибо за все ответы. Кажется, что это была ошибка в ассемблерном коде, а не компилятор Intel, который не использовал ассемблерный код.

1

Решение

Ваш ассемблерный код уничтожает EBX зарегистрируйтесь (как отметил Jongware), и, вероятно, именно поэтому второй цикл в вашем коде C ++ выполняется только один раз. Если i хранится в EBX затем меняется EBX до 2000 в Add вызовет следующий тест условия цикла i < 100 терпеть неудачу.

Вам нужно либо сохранить и восстановить EBX зарегистрируйтесь в вашем ассемблерном коде или вам нужно выбрать другой регистр, который, как предполагается, не сохраняется при вызовах функций (EAX, EDX, или же ECX).

3

Другие решения


По вопросам рекламы [email protected]