Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.216.190.167] |
|
Страницы: (2) 1 [2] все ( Перейти к последнему сообщению ) |
Сообщ.
#16
,
|
|
|
Запилил-таки на fasm'е, за одно и узнал как я отстал от жысти!
Размер экзешника получился прекрасный - 3072 байта format PE console entry start ; ***************************************************************************** ; timer.exe - Утилита замера времени исполнения программы, задаваемой в ; коммандной строке. fasm 1.73.22 ; ; Copyleft (L) 2020 Majestio AKA JoeUser = http://majestio.info ; ; ***************************************************************************** ; Если командная строка содержит пробелы - ее записываем в кавычках! ; ; ***************************************************************************** include 'win32wx.inc' ;======================================= section '.data' data readable writeable ;======================================= argstr TCHAR 13,10,'Launch: "%s" ... ',13,10,13,10,0 usagestr TCHAR 13,10,'Usage: timer.exe <"cmd">',13,10,0 okstr TCHAR 13,10,'Done : %.5f sec',13,10,0 erstr TCHAR 13,10,'Error (%d)!',13,10,0 ;======================================= section '.bss' data readable writeable ;======================================= SystemInfo STARTUPINFO ProcessInfo PROCESS_INFORMATION argc dd 0 ; количество аргументов командной строки argv dd 0 ; ссылка на cnt1 dq 0 ; счетчик начала cnt2 dq 0 ; счетчик завершения freq dq 0 ; делитель частоты ;======================================= section '.code' code readable executable ;======================================= start: invoke GetCommandLineW invoke CommandLineToArgvW, eax, addr argc mov [argv], eax ; проверяем, что аргумент ровно один ARGV[1] (ARGV[0] есть всегда) mov eax,[argc] cmp eax,2 jne usage ; заносим в argv - ARGV[1] mov eax, [argv] mov eax, [eax+4] mov [argv], eax ; Печатаем название запускаемой программы invoke wprintf, argstr, [argv] mov [SystemInfo.cb],sizeof.STARTUPINFO invoke GetStartupInfoW, SystemInfo or [SystemInfo.dwFlags],STARTF_USESHOWWINDOW mov [SystemInfo.wShowWindow],SW_HIDE ; Чекаем таймер invoke QueryPerformanceFrequency, addr freq test eax, eax jnz @f mov eax, 1; Error 1 jmp error @@: invoke QueryPerformanceCounter, addr cnt1 test eax, eax jnz @f mov eax, 2; Error 2 jmp error ; Запускаем процесс @@: invoke CreateProcess,0,[argv],NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,SystemInfo,ProcessInfo test eax,eax jnz @f mov eax, 3; Error 3 jmp error ; ждем завершения процесса @@: invoke WaitForSingleObject, [ProcessInfo.hProcess], -1 cmp eax, 0xFFFFFFFF jne @f mov eax, 4; Error 4 jmp error ; Закрываем хендлы @@: invoke CloseHandle, [ProcessInfo.hProcess] test eax,eax jnz @f mov eax, 5; Error 5 jmp error @@: invoke CloseHandle, [ProcessInfo.hThread] test eax,eax jnz @f mov eax, 6; Error 6 jmp error ; Чекаем таймер @@: invoke QueryPerformanceCounter, addr cnt2 test eax,eax jnz @f mov eax, 7; Error 7 jmp error ; Считаем время @@: finit fild qword [cnt2] fild qword [cnt1] fsubp fild qword [freq] fdivp fstp qword [cnt1] ; Выводим время в секундах в виде double:qw invoke wprintf, okstr, dword[cnt1], dword[cnt1+4] jmp exit usage: invoke wprintf, usagestr jmp exit error: invoke wprintf, erstr, eax exit: invoke ExitProcess, 0 ;==================================== section '.idata' import data readable ;==================================== library kernel,'kernel32.dll',\ shell32,'shell32.dll',\ msvcrt,'msvcrt.dll' import kernel,\ QueryPerformanceFrequency,'QueryPerformanceFrequency',\ QueryPerformanceCounter,'QueryPerformanceCounter',\ CloseHandle,'CloseHandle',\ GetStartupInfoW,'GetStartupInfoW',\ WaitForSingleObject,'WaitForSingleObject',\ ExitProcess,'ExitProcess',\ CreateProcess,'CreateProcessW',\ GetCommandLineW,'GetCommandLineW' import shell32,\ CommandLineToArgvW,'CommandLineToArgvW' import msvcrt,\ wprintf,'wprintf' Зато wprintf выводит прекрасно Я этим в коде, кстати, времечко и вывожу из double. |
Сообщ.
#17
,
|
|
|
Цитата JoeUser @ wprintf не WinAPI, это RTL. Если же в RTLless тащить плавающую точку, линковать с стандартными символами, которые я же и отключил, ещё сложнее, чем с llmul и lldiv Зато wprintf выводит прекрасно Я этим в коде, кстати, времечко и выводу из double. Добавлено Цитата JoeUser @ Я бы перетащил первую перед WaitForSingleObject(), вторую после QueryPerformanceCounter(). Чуть точнее будет. ...CloseHandle... |
Сообщ.
#18
,
|
|
|
Ну сидит оно в msvcrt.dll и сидит себе - эта дээлелька дефакто всегда в системе. Не?
|
Сообщ.
#19
,
|
|
|
Плюс ты не учитываешь возможные параметры для запускаемого процесса. Представь, что тебе надо замерить время для %comspec% / c call BuildCMakeScript.bat
Добавлено Цитата JoeUser @ Не помню. Но коли на динамическую RTL завязываться, то и на C++ можно получить ~15Кб. Ну сидит оно в msvcrt.dll и сидит себе - эта дээлелька дефакто всегда в системе. Не? |
Сообщ.
#20
,
|
|
|
Цитата Qraizer @ Чуть точнее будет. Думал над этим, но так захотелось сперва хэндлы позакрывать - прямо кушать не могу! Добавлено Цитата Qraizer @ %comspec% / c call BuildCMakeScrupt.bat Не не не ... я спецом эту муть сразу выкинул! Есть там функция раскрытия окружения ... знаю, так можно еще и начать в проге собирать все ARGV в одну строку, парсить, через жэ со знаками пунктуации сражаться. Для удобства придумали командные файлы! Хочешь какой-то пакет программ затестить - пиши батник потом его "cmd /c batbatbat.cmd", и все . А уж в батнике что хошь "резольвь". Моя задача была написать оч маленький и шустрый утиль. Это все. |
Сообщ.
#21
,
|
|
|
Та дело не %comspec% же. Ну пиши своё cmd /c batbatbat.cmd, всё равно ж у тебя параметры-то.
|
Сообщ.
#22
,
|
|
|
Запускаю - timer.exe "cmd /C package.bat" ... Все запускается, все чекается. Просто проверь, если ты командную строку обрамишь двойными кавычками, то она вся полностью залезет в ARGV[1], а не будет дробиться. Вот это и пользую.
|
Сообщ.
#23
,
|
|
|
Ну, дело хозяйское. Но как по мне, если можно избавиться от человеческого фактора легко и просто посредством
const char *getCmdLine(const char *cmd) { if (*cmd == '"') while(*++cmd != '"') ; while (*cmd != ' ') ++cmd; while (*cmd == ' ') ++cmd; return cmd; } /* ... */ const char *commandLine = getCmdLine(GetCommandLine()); Добавлено Ну и по-хорошему после CommandLineToArgvW() нужен LocalFree() |
Сообщ.
#24
,
|
|
|
Цитата Qraizer @ Ну и по-хорошему после CommandLineToArgvW() нужен LocalFree() Да, не дочитал хелп, позже исправлю. Добавлено Цитата Qraizer @ Но как по мне, если можно избавиться от человеческого фактора легко и просто посредством Ага ... а потом еще ExpandEnvironmentStringsW добавить, а потом ... встроенную html-справку Своих зайцев я убил: чем камни гонять и считать бэйнчи - у меня есть, до асма добрался и оттопырился ... на время хоть от этого Qt отвлекся. |
Сообщ.
#25
,
|
|
|
Цитата JoeUser @ Иконку с текущими секундами в трей, менюху по правому клику с About и Break, автоапдейт с https... Придумать много можно, только это несерьёзно. А человеческий фактор серьёзно, у меня бы этот код ревью не прошёл. Ага ... а потом еще ExpandEnvironmentStringsW добавить, а потом ... встроенную html-справку |
Сообщ.
#26
,
|
|
|
Цитата Qraizer @ легко и просто посредством Хороший код, но от кривожопов на 100% не спасает! Если не кавычка, так пробел ... демо |
Сообщ.
#27
,
|
|
|
Qraizer. хотя, если честно с ExpandEnvironmentStringsW я может быть бы еще согласился ... изредка бывает нужно вспомнить где этот %CARGO_HOME%, к примеру. Раз в месяц Но я пошел в пляс от Бритвы Оккамы - сделал то, что нужно сегодня мне, самому хорошему и скромному человеку в солнечной системе. Для усталых, невнимательных, тупых, слепых - могу сделать завтра, только оплатите мне абонемент в бассейн на месяц с девушками!
|
Сообщ.
#28
,
|
|
|
Цитата Qraizer @ Ну и по-хорошему после CommandLineToArgvW() нужен LocalFree() Хотя ... не буду. Формально - ты прав! Но, в моем случае, это происходит один раз - и утечка электронного мозга, как таковая, нивилируется просто завершением процесса. Но, на заметочку себе оставлю. Сообщения были разделены в тему "Измерение времени выполнения кода" |
Сообщ.
#29
,
|
|
|
Отчасти ты прав. Но многие наверное забыли мат.статистику ... Простой пример. У нас есть эмпирическая выборка из 1000 величин. По сути - выборка: 1) Означает какое-то влияние 2) У этого влияния есть какой-то коэффициент 3) У эмпирически собранных данных есть разброс - это де факто Но есть еще и Ситуация Йопта) когда по какой-то причине сбиваются вычисления/отсчеты. Напомню, как поступают бородатые дядьки... в плане их собственной "нормализации" 1) Все величины сортирют 2) Начинают отсекать "экстремумы". Для этого делят весь отрезок на 4 части. Из частей 2-3 получают либо среднне, либо средне-квадратичное 3) Из отрезков 1 и 4 начинают удалять значения, которые по модулю разности меньше вычлененных значений и удаляемых более, чем в два раза 4) Если число усечений справа и слева не превышает 20-25% - получают верный коэффициент влияния 5) Если не получилось - или повторяют, или утверждают, что эксперимент носит вааще никакую детерминированность (типа искать не тут, давайде другие данные) Спрашивается а при чем тут "милисекунды"? А они просто - часть эксперимента. Запустив 1000 раз одно и то же здание в реальных условиях (загружжености компа, незагруженности) - мы выйдем к "СРЕДНЕМУ". По методе, как я описал выше. Коэффициент какойта! Как назвать, сами считайте - скорости, мощности, офигительности ... |