Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Asm: Общие вопросы > Тест на производительность |
Автор: Coder 3.4.2005, 01:34 | ||||||
Решил протестировать C++, Pascal и Asm на производительность кода. Вот три исходника:
Так вот, получились интересные результаты, программа на C++ и Pascale выполняются за ~14 сек., а на Asm за (!) ~46 сек. Почему такая ерунда происходит? я думал, что все должно быть наоборот - ведь на Асме идет прямое обраещение к процессору... где же быстродействие ассемблера? P.S. используемые компиляторы: С++ - Turbo C++ 3.0 Pascal - Borland Pascal 7.0 Asm - MASM32 7.0 P.S.2. еще мое наблюдение, при выполнение кода Паскаля и С загружен процесс ntvdm.exe, а при выполнении кода Asm загружен процесс csrss.exe. почему эти программы выполняются в разными процессами? |
Автор: cardinal 3.4.2005, 01:53 | ||||
Потому что, твой компилятор сделал все лучше, чем то, что сделал ты сам (то, что сделано на asm'е).
В более хитром подходе ![]() Любой компилятор (не asm) перед тем как сделать exe'шник как бы создает asm, а потом уже делает понятный для процессора файл с коммандами. Некоторые компиляторы позволяют посмотреть на то, что они делают сами (создают asm листинги) и ты можешь подумать над тем, а нельзя ли сделать это лучше самому. В твоем примере последнее не получилось ![]() Рассказал все своими словами, может не очень получилось ![]() |
Автор: S.A.P. 3.4.2005, 02:38 |
Могу предположить, что из за того, что Pascal и C++ у тебя досовские, а приложение на Асме - виндовое. Консоль - это не Dos приложение. Dos овские компилеры, например, вместо вызова wsprintf используют свой код и так, возможно будет быстрее, потому - что в асме ты принудительно обращаешься к функции в DLL, а Dos компилер может все это оптимизировать в инлайн функцию. Да и WriteConsoleA DOS компилер не использует, ее может использовать процесс, который эмулирует Dos приложение. Но это только ИМХО. |
Автор: Coder 3.4.2005, 07:52 |
cardinal, покажи более хитрый подход! |
Автор: Chingachguk 3.4.2005, 10:53 | ||
Где ты увидел прямое обращение к процессору ? wsprintf - это API, так что это просто вызовы Win. К тому же у тебя два вызова WriteConsoleA в асме, а в СИ и Паскале наверняка один. Про то, что СИ и Пас под дос, а асм - для win, уже сказали. |
Автор: cardinal 3.4.2005, 13:53 | ||
а ты поставь себе MS VC++ и эксперементируй там. Создашь listing и исходя из него будешь оптимизировать (поправляя то, что стоит в _asm{} ![]() А во-вторых попробуй вместо loop сделать просто dec. Помоему когда я экспериментировал у меня так быстрее получалось. Когда добьешься оптимального результата можешь его использовать в другом C/C++ компиляторе (если он конечно _asm делать позволяет)... |
Автор: oleg1973 3.4.2005, 19:29 |
давайте тестить printf из crtdll.dll |
Автор: Coder 5.4.2005, 08:16 | ||||||
пользуясь всем вышепосоветованным решил проверить просто скорость прогонки циклов на этих языках (без вызова каких либо операторов, функций) но брал уже цикл от 2`000`000`000 до 0.
Вот такие результаты: Asm - ~5 сек Pascal - ~3 сек !!! C++ - ~16.5 сек ну вроде все убрал остались гольные цифры и оказывается компилятор паскаля с ними справляется лучше... |
Автор: S.A.P. 5.4.2005, 08:48 | ||
Coder во первых убери строчку cmp eax,0. Инструкция DEC сама выставляет флаг признака нуля. Во вторых сравни количество нулей у числа в C++ и Pascal и ASM ![]() В третьих в С++ попробуй и такой цикл замутить
В четвертых посмотри в опциях компилатора всякие оптимизации по скорости. |
Автор: S.A.P. 5.4.2005, 10:10 | ||
Вот как оптимизирует цикл Visual C++
Разницы с ассемблером нет. А если убрать строчку _asm NOP, то вобще весь цикл вырезает. Посмотрим, как с этим Борланд справится. Уже на глаз можно прикинуть, что Pascal обделается в этом тесте. |
Автор: Girder 5.4.2005, 15:19 | ||||||
![]() ![]() ![]() Код:
|
Автор: S.A.P. 5.4.2005, 15:46 | ||||||
чем этот код
будет быстрее этого
![]() Тем более Visual C++ вобще пустые циклы вырезает. |
Автор: Girder 5.4.2005, 15:49 | ||
Вот ентот код (особенно на старых компьютерах) будет медленнее:
![]() PS: И не надо мне советовать комп поменять... я его мож подарить хочу ![]() ![]() |
Автор: S.A.P. 5.4.2005, 16:01 | ||||||
Щас по другому проверим ![]() Претендент:
Добавлено @ 16:04
Добавлено @ 16:05
![]() |
Автор: Girder 5.4.2005, 17:20 | ||
Чего и то у тебя было 200000000 стало 2000000000 Тестируй:
![]() |
Автор: Coder 7.4.2005, 12:05 | ||||||||||||
Ой, извиняюсь ![]()
С какой версии VC++ есть такой оптимизатор? Есть ли такие возможности у C++Builder? (Я никогда не писал на С++ под виндой). Что посоветуете C++Builder или VC++?
А что (какой компилер) это так код преобразовало? интересный подход и странный подход... ладно тут 2млрд, а если бы было число 10 в 2 байтовом регистре, он бы че весь 4 байтовый регистр ворошил на больших числах (начиная с 4294967286)?
Athlon 952 ![]() |
Автор: mb78 31.7.2008, 14:30 |
Если сделать на ассемблере под Dos , но не через прерывания а через запись в память (правда сначала надо сформировать свою быструю подпрограмму вывода целых чисел) то я думаю такая программа будет длиться меньше секунды. Для программ Dos число 100000 повторений в 10-чной системе счисления это ничто. Dos может перебрасывать блоки по 65535(ffffh) сотни раз в секунду. А в Windows почти весь вывод на экран происходит через API , многие из которых работают очень медленно. Например я пробовал закрашивать небольшой квадратик через API функцию SetPixel , и у меня программа длилась несколько секунд. К тому же в Windows работает сразу много процессов поэтому они замедляют друг друга.Для лучшей проверки вашего теста попробуйте загрузить Windows в безопасном режиме , там меньше процессов и пограммы выполняются быстрее, например у меня в несколько раз. А почему в С+ получилось быстрее,я думаю возможно оттого , что в С+ для быстродействия вывод сначала идет не не экран , а в память , и перебрасывается на экран несколько раз в секунду все содержимое что нужно вывести. |
Автор: Diabolus 24.9.2008, 15:06 | ||
0m1.352s (P4 - 3GHz) |