Буду краток: написал программу вычисления чисел фибоначи на C++ (Ms Visual Studio Express 2005), затем дизассемблировал и скомпилил этот ассемблерский код на Masm 8, установленной на MSVS Express. Время выполнения программы на С++ - 11с на Asm - 14с. Как это возможно? При этом параметры проектов одинаковые.
Хе, вот так вот просто дизассемблировал и скомпилил? Со всеми пустыми/бесполезными/вредными для ассемблера инструкциями, порождёнными С-компилятором? Думаю, если изначально писать на асм тот же алгоритм, будет быстрее...
Я думаю тут просто разной длины инструкции получились (например переходы или запись констант) Там с выравниванием в памяти у процика разные траблы выходят. Как на чтение данных так и комманд (одно и тоже).
Я оптимизировал ассемблерский код, и программа отработала быстрей - 9с. Но всё таки интересно почемы одинаковый асм код, сгенерированный C-компилятором и ассемблером, работает с разной скоростью (при одном линковщике). И главное как выравнить скорость (в лучшую сторону), не изменяя код.
Потому, что измеряешь неправильно - секундомером или песочными часами ? ) Код совершенно идентичный, поэтому и цикл вычисления должен работать одинаковое время Добавь по человечески GetTickCount в начало и в конец цикла и сравни
Если у тебя получились одиноковые асм-команды, это еще не значит что бинарно они будут совпадать. Кроме того, код может выравниваться по разному. В идеале, правильно замерять время вычисления с помощью GetThreadTimes.
alpet В данном случае exe-образы практически идентичны - секция кода точно один ко одному, остальное - на вскидку Поэтому дело только в некорректных измерениях, хотя тут имхо и сравнивать то незачем, раз бинарный код и адреса одни и те же
Я измерял время работы программы обычным секундомером, с погрешностью меньше полусекнуды (большой опыт на лабораторных в универе), а разница во времени 14-11=3 секунды. Для Athlon64 4200+ X2 это много машинного времени, так что дело не в измерениях. В exe-шниках рабочая часть почти идентичная: Дизассемблированный код программы на асм: Код (Text): 0x40100C: B801000000 MOV EAX,0x1 0x401011: 33D2 XOR EDX,EDX 0x401013: BEA0860100 MOV ESI,0x186A0 0x401018: 8D2424 LEA ESP,DWORD PTR [ESP] 0x40101B: 8BC8 MOV ECX,EAX 0x40101D: 8BC2 MOV EAX,EDX 0x40101F: 83EE01 SUB ESI,0x1 0x401022: 03C1 ADD EAX,ECX 0x401024: 85F6 TEST ESI,ESI 0x401026: 8BD1 MOV EDX,ECX 0x401028: 7FF1 JG 0x40101B 0x40102A: 83EF01 SUB EDI,0x1 0x40102D: 85FF TEST EDI,EDI 0x40102F: 7FDB JG 0x40100C на С++ Код (Text): 0x401010: B801000000 MOV EAX,0x1 0x401015: 33D2 XOR EDX,EDX 0x401017: BEA0860100 MOV ESI,0x186A0 0x40101C: 8D642400 LEA ESP,DWORD PTR [ESP] 0x401020: 8BC8 MOV ECX,EAX 0x401022: 8BC2 MOV EAX,EDX 0x401024: 83EE01 SUB ESI,0x1 0x401027: 03C1 ADD EAX,ECX 0x401029: 85F6 TEST ESI,ESI 0x40102B: 8BD1 MOV EDX,ECX 0x40102D: 7FF1 JG 0x401020 0x40102F: 83EF01 SUB EDI,0x1 0x401032: 85FF TEST EDI,EDI 0x401034: 7FDA JG 0x401010 Разница межну кодами: Асм 5 2 5 3 2 2 3 2 2 2 2 3 2 2 C++ 5 2 5 4 2 2 3 2 2 2 2 3 2 2
asm: JG 0x40101B JG 0x40100C c++: JG 0x401020 JG 0x401010 Замечаете разницу в выравнивании? Не делайте так больше, а то тему перенесут в раздел "Улыбнитесь".
Aleus Essentia А почему в файлах Fibonachi.exe и FibonachiAsm.exe из первого аттача выравнивание одинаковое - может ты один и тот же файл под разными именами подсунул ?! Ес-но выравнивание на атлонах и P6 для "тонких" циклов имеет существенное значение, причем не столько выравнивание метки цикла, сколько "укладывание" тела цикла в 16-байтный блок. А у тебя в асмовском варианте инструкция sub esi,1 режется границей блока -> сама задерживается на такт и задерживает test esi,esi и в результате вместо 3 тактов на внутренний цикл получается 4