Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.235.120.15] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Всем привет, особенно Jin X (с целью подмазаться) !
В уиндовс так не хватает линуксовой команды 'time' ... вот я и подумал, а почему бы ее не запилить на ассемблере?! Но, увы, столько времени утекло - где я, и где ассемблер Поэтому просьба, как в том фильме "вельми понеже, паки-паки, иже херувимы" (С) поделитесь наработками, плс! Нужно: * считать argv[1] * запустить таймер высокого разрешения * запустить argv[1] как процесс * остановить таймер высокого разрешения * вернуть или затраченное время процессом, или сообщение об ошибке запуска Почему на асме? С++ компилеры выдают жЫрноту, меня это бесит - тут на максмимум 3кб размер исполняемого файта. Ассемблер интересен. Можно запилить на голом Си+плюшки (используя к примеру LCC) ... но это уже будет другая песня не об этом. И еще ... если такая возможность есть - не линковать CRT.DLL. Чем "автономней исполняемый модуль - тем лучше, и пофик на лишний килобайт. |
Сообщ.
#2
,
|
|
|
Цитата JoeUser @ Есть QueryPerformanceCounter и QueryPerformanceFrequency.В уиндовс так не хватает линуксовой команды 'time' Т.е. читаем QueryPerformanceCounter до запуска, QueryPerformanceCounter после запуска, считаем разницу и делим на QueryPerformanceFrequency, получаем секунды. Запуск – CreateProcess. Вывести можно, если писать на MASM32 через функции встроенной библиотеки: StdOut, dw2a (или wsprintf – это не msvcrt). А чем, собственно, msvcrt не устраивает? Проще всего ж использовать printf. Но не знаю, насколько такой таймер реально оправдан, ведь на запуск тоже уйдёт какое-то время и внесёт свою погрешность, так что, может, GetTickCount достаточно? |
Сообщ.
#3
,
|
|
|
цыгвин
|
Сообщ.
#4
,
|
|
|
Jin X, пасип ... я позже зайду!
|
Сообщ.
#5
,
|
|
|
Цитата Gonarh @ Иван Иваныч? цыгвин |
Сообщ.
#6
,
|
|
|
Цитата Gonarh @ цыгвин Cygwin? Ай донт андерстенд! |
Сообщ.
#7
,
|
|
|
Цитата JoeUser @ Cygwin? Яя, натюрлих. |
Сообщ.
#8
,
|
|
|
Цитата JoeUser @ Гм, "жЫрнота" будет везде:Почему на асме? С++ компилеры выдают жЫрноту, меня это бесит - тут на максмимум 3кб размер исполняемого файта. С++, писано за 10 минут, один сеанс отладки, размер образа от Студии 214к #include <windows.h> # #include <chrono> #include <iostream> #include <vector> #include <string> int main(int argn, char *argv[]) { PROCESS_INFORMATION procInfo; STARTUPINFO startInfo= { sizeof(startInfo), NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, STARTF_FORCEOFFFEEDBACK, 0, 0, NULL, NULL, NULL, NULL}; std::string cmdLine; for (int i = 1; i < argn; ++i) cmdLine.append(argv[i]) += ' '; if (cmdLine.empty()) return std::cout << "App for run is absent\n", 1; std::vector<char> appName(std::begin(cmdLine), std::end(cmdLine)); appName[appName.size()-1] = '\0'; auto start = std::chrono::system_clock::now(); if (CreateProcess(NULL, &appName.front(), NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &startInfo, &procInfo) == 0) return std::cout << "Error of " << argv[1] << " launch. Error code is " << GetLastError() << '\n', 1; else { CloseHandle(procInfo.hThread); WaitForSingleObject(procInfo.hProcess, INFINITE); auto now = std::chrono::system_clock::now(); CloseHandle(procInfo.hProcess); std::cout << "Time of run is " << std::chrono::duration_cast<std::chrono::milliseconds>(now - start).count() << " ms.\n"; } return 0; } С, писано за 35 минут, 6 сеансов отладки, размер образа от Студии 100к #include <windows.h> # #include <malloc.h> #include <string.h> #include <stdio.h> int append(char **dst, const char *src) { size_t srcLen = strlen( src), dstLen = strlen(*dst); char *newDst =realloc(*dst, dstLen + srcLen + 1); if (newDst == NULL) return 0; *dst = newDst; strcat(*dst, src)[dstLen + srcLen] = ' '; (*dst)[dstLen + srcLen + 1] = '\0'; return 1; } int main(int argn, char *argv[]) { PROCESS_INFORMATION procInfo = { NULL }; STARTUPINFO startInfo= { sizeof(startInfo), NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, STARTF_FORCEOFFFEEDBACK, 0, 0, NULL, NULL, NULL, NULL}; char *cmdLine = calloc(1, 1); int res = 1, i; if (cmdLine == NULL) { printf("Insufficient memory\n"); goto cleanup; } for (i = 1; i < argn; ++i) if (!append(&cmdLine, argv[i])) { printf("Insufficient memory\n"); goto cleanup; } if (cmdLine[0] == '\0') { printf("App for run is absent\n"); goto cleanup; } cmdLine[strlen(cmdLine)-1] = '\0'; LARGE_INTEGER start, now, freq; if (QueryPerformanceFrequency(&freq) == 0) { printf("Time service is unavailable. Error code is %u\n", GetLastError()); goto cleanup; } if (QueryPerformanceCounter(&start) == 0) { printf("Fault of time service request for start. Error code is %u\n", GetLastError()); goto cleanup; } if (CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &startInfo, &procInfo) == 0) { printf("Error of %s launch. Error code is %u\n", argv[1], GetLastError()); goto cleanup; } CloseHandle(procInfo.hThread); WaitForSingleObject(procInfo.hProcess, INFINITE); if (QueryPerformanceCounter(&now) == 0) { printf("Fault of time service request for finish. Error code is %u\n", GetLastError()); goto cleanup; } printf("Time of run is %llu ms\n", (now.QuadPart - start.QuadPart) * 1000 / freq.QuadPart); res = 0; cleanup: if (cmdLine != NULL) free(cmdLine); if (procInfo.hProcess != NULL) CloseHandle(procInfo.hProcess); return res; } Для 3-х кб нужно выключить стандартные библиотеки и юзать только WinAPI. Последний вариант несложно адаптировать, просто умножаем время и отладку ещё на два. P.S. wsptintf() не умеет вывод long long. WinAPI, поиск сырцов в crt\srс\i386 и "портирование" за полчаса, четыре сеанса отладки, размер образа от Студии 3,5к #include <windows.h> # #include <stdarg.h> #define OUT_BUFFER_SIZE 1024 int wprintf(LPCTSTR fmt, ...) { char out[OUT_BUFFER_SIZE]; va_list args; int written; va_start(args, fmt); written = wvsprintf(out, fmt, args); va_end(args); WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), out, written, &written, NULL); return written; } const char *getCmdLine(const char *cmd) { if (*cmd == '"') while(*++cmd != '"') ; while (*cmd != ' ') ++cmd; while (*cmd == ' ') ++cmd; return cmd; } int entryPoint(void) { PROCESS_INFORMATION procInfo = { NULL }; STARTUPINFO startInfo= { sizeof(startInfo), NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, STARTF_FORCEOFFFEEDBACK, 0, 0, NULL, NULL, NULL, NULL}; const char *commandLine = getCmdLine(GetCommandLine()); int res = 1, i; char *cmdLine; if (*commandLine == '\0') { wprintf("App for run is absent\n"); goto cleanup; } cmdLine = HeapAlloc(GetProcessHeap(), HEAP_NO_SERIALIZE, lstrlen(commandLine)+1); if (cmdLine == NULL) { wprintf("App for run is absent\n"); goto cleanup; } lstrcpy(cmdLine, commandLine); LARGE_INTEGER start, now, freq; if (QueryPerformanceFrequency(&freq) == 0) { wprintf("Time service is unavailable. Error code is %u\n", GetLastError()); goto cleanup; } if (QueryPerformanceCounter(&start) == 0) { wprintf("Fault of time service request for start. Error code is %u\n", GetLastError()); goto cleanup; } if (CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &startInfo, &procInfo) == 0) { wprintf("Error of %hs launch. Error code is %u\n", cmdLine, GetLastError()); goto cleanup; } CloseHandle(procInfo.hThread); WaitForSingleObject(procInfo.hProcess, INFINITE); if (QueryPerformanceCounter(&now) == 0) { wprintf("Fault of time service request for finish. Error code is %u\n", GetLastError()); goto cleanup; } wprintf("Time of run is %lu ms\n", (unsigned long)((now.QuadPart - start.QuadPart) * 1000 / freq.QuadPart)); res = 0; cleanup: if (cmdLine != NULL) HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, cmdLine); if (procInfo.hProcess != NULL) CloseHandle(procInfo.hProcess); return res; } Строки для компиляции и линковки: ml -c lldiv.asm llmul.asm cl -O1 -GL -Zl -GS- сырец.c lldiv.obj llmul.obj user32.lib kernel32.lib -link /NODEFAULTLIB /ENTRY:entryPoint /SUBSYSTEM:CONSOLE Цитата JoeUser @ Это совсем другой вопрос. P.S. Последний сырец к услугам. Ассемблер интересен. |
Сообщ.
#9
,
|
|
|
Qraizer, а почему system_clock, а не high_resolution_clock?
|
Сообщ.
#10
,
|
|
|
Та без разницы. Миллисекунды же. Если миллисекунд вдруг мало, то да.
|
Сообщ.
#11
,
|
|
|
Цитата Qraizer @ Оно того точно стоило? Да! Вот это красиво, если оно так (пока не проверил)!!! И утиль полезный, и реализация на достойном уровне. Пасип! ЗЫ: Но с с асмом я всеж позже разберусь - хотелось увидеть куски кода для этих под-задач. Наверняка они привычны и злободневны для асм-писателей. |
Сообщ.
#12
,
|
|
|
Qraizer, кстати ... а ты когда-нить смотрел в сторону lcc?
Описалово и линки, дистр x32, дистр x64, есличо. Добавлено Цитата Jin X @ Т.е. читаем QueryPerformanceCounter до запуска, QueryPerformanceCounter после запуска, считаем разницу и делим на QueryPerformanceFrequency, получаем секунды. Ну пока, "на коленке", я вот такое намутил: @echo off SET RUN="ffmpeg -f rawvideo -pix_fmt yuv420p -s:v 1152x864 -r 25 -i out.yuv -i out.mp3 -c:v libx265 -preset veryfast -c:a libvorbis -shortest res.mkv" PowerShell -NoProfile -ExecutionPolicy Bypass Measure-Command {%RUN%} > test-1-res.txt Но нормальную утилиту time я уже вчера хочу! Добавлено Цитата JoeUser @ Qraizer, кстати ... а ты когда-нить смотрел в сторону lcc? И еще вот это ... что скажешь с точки зрения С++ профи? Сорри за оффтоп - просто уж больно интересная шляпа!!!!! Очень хочется с "иглы Qt" соскочить Добавлено Скрытый текст Цитата Qraizer @ Оно того точно стоило? И есчо !!! Если приаттачить lldiv.asm llmul.asm, то твои труды неплохо было бы в FAQ C++ выложить. Мыже исходники, или где?! |
Сообщ.
#13
,
|
|
|
Цитата Qraizer @ Так, человек же даже в заголовке написал: "[Т]аймер высокого разрешения" Та без разницы. Миллисекунды же. Если миллисекунд вдруг мало, то да. |
Сообщ.
#14
,
|
|
|
А чем миллисекунды не высокое, Jin X? Цифры не указаны, и я выбрал миллисекунды из практических соображений вокруг формулировки задачи. Ну и если придираться, нужно ещё убедиться, что QueryPerformanceFrequency() вернёт подходящие цифры. Впрочем, и решить задачу задачи не ставил, иначе на ассме б выложил. А так помог, на сколько было не жалко времени, перевести последний вариант на асм – вопрос желания, а не усилий.
Нет, не смотрел, JoeUser. На что там стоит смотреть? Ну компилятор и компилятор, чем он примечателен, чтоб на него обратить внимание? Ну, кроме лицензии, которую нынче и VS покрывает. За nano слышал, хвалили, не юзал. Цитата JoeUser @ Это стандартные файлики из поставки сырцов RTL в VS. Компилятор их использует для умножения и деления 64-битных целых. Так-то они лежат в либах, но т.к. те отключены, нужно подкинуть свою реализацию. Мне было лень, я компильнул оригиналы. И нужны они только для 32-битного кода, в 64-х битах компилятор сам справляется с 64-битной арифметкой. Если приаттачить lldiv.asm llmul.asm, то твои труды неплохо было бы в FAQ C++ выложить. |
Сообщ.
#15
,
|
|
|
Цитата Qraizer @ Вообще, я согласен, что при запуске внешней проги, считать точнее, чем в миллисекундах, нет особого смысла.и я выбрал миллисекунды из практических соображений вокруг формулировки задачи Цитата Jin X @ Это про микро/наносекунды. не знаю, насколько такой таймер реально оправдан, ведь на запуск тоже уйдёт какое-то время и внесёт свою погрешность, так что, может, GetTickCount достаточно? |