Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.223.172.252] |
|
Сообщ.
#1
,
|
|
|
Windows 7, Visual Studio 2010. В программе:
#include <string> #include <iostream> #include <Windows.h> #include <stdio.h> using namespace std; void AddArrays(int n, const int* const pA, const int* const pB, int* const pC) { DWORD StartTimeWin, ElapsedTimeWin; StartTimeWin = timeGetTime(); for(int i = 0; i < n; ++i) { pC[i] = pA[i] + pB[i]; } ElapsedTimeWin = timeGetTime() - StartTimeWin; cout << ElapsedTimeWin << "\t\t pC[i] = pA[i] + pB[i]" << endl; } int main() { setlocale(LC_ALL, ""); int n = 15000; int* pA = (int*) malloc(sizeof(int)*n); int* pB = (int*) malloc(sizeof(int)*n); int* pC = (int*) malloc(sizeof(int)*n); for(int i = 0; i < n; ++i) { pA[i] = i; pB[i] = i; pC[i] = 0; } AddArrays( n, pA, pB, pC); free(pA); free(pB); free(pC); system("\npause"); return 0; } error LNK2019: ссылка на неразрешенный внешний символ __imp__timeGetTime@0 в функции "void __cdecl AddArrays(int,int const * const,int const * const,int * const)" (?AddArrays@@YAXHQBH0QAH@Z) D:\MyProgramming\CpuGpu\CpuGpu.obj Не понимаю, почему ссылка на API функцию timeGetTime является неразрешенной. Помогите, пожалуйста, разобраться. Проект прикрепил. Прикреплённый файлCpuGpu.zip (2,08 Кбайт, скачиваний: 102) |
Сообщ.
#2
,
|
|
|
Подключи в свойствах проекта, в опциях линкера, Winmm.lib
|
Сообщ.
#3
,
|
|
|
tuchin
1) Зачем использовать timeGetTime, если она практически ничем не отличается от "стандартной" GetTickCount? 2) Обе эти функции выдают результат с дискретом, равным периоду системного таймера, стандартное значение которого составляет 1/64 с = 15.625 мс. Для замера времени AddArrays при n = 15 тыс. это слишком грубо. Нужно либо увеличить n, либо использовать функции QueryPerformanceCounter + QueryPerformanceFrequency (о чем собс-но и говорится в описании timeGetTime) |
Сообщ.
#4
,
|
|
|
Олег М, спасибо, заработало.
leo, спасибо за информацию, попробую QueryPerformanceCounter |
Сообщ.
#5
,
|
|
|
M Не забываем про использование функции "Вопрос решён!" |
Сообщ.
#6
,
|
|
|
У меня получилось так, что timeGetTime и QueryPerformanceCounter дают приблизительно близкие результаты (для милисекунд), а вот результаты GetTickCount могут сильно от них отличаться (1 запуск - 4, 0, 4.602; 2 запуск- 4, 0, 4.38 и т.д.)
#include <string> #include <iostream> #include <Windows.h> #include <stdio.h> using namespace std; #pragma comment(lib, "winmm.lib") void AddArrays(int n, const int* const pA, const int* const pB, int* const pC) { LARGE_INTEGER StartTimeQP, StopTimeQP, FreqQP; DWORD StartTimeWin = timeGetTime(); DWORD StartTimeGetTick = GetTickCount(); QueryPerformanceCounter(&StartTimeQP); for(int i = 0; i < n; ++i) { pC[i] = pA[i] + pB[i]; } DWORD ElapsedTimeWin = timeGetTime() - StartTimeWin; DWORD ElapsedTimeGetTick = GetTickCount() - StartTimeGetTick; QueryPerformanceCounter(&StopTimeQP); QueryPerformanceFrequency(&FreqQP); double ElapsedTimeQP = 1000.0 * (double) (StopTimeQP.QuadPart - StartTimeQP.QuadPart)/ (double) FreqQP.QuadPart; cout << ElapsedTimeWin << "\t\t pC[i] = pA[i] + pB[i] timeGetTime mc" << endl; cout << ElapsedTimeGetTick << "\t\t pC[i] = pA[i] + pB[i] GetTickCount mc" << endl; cout << ElapsedTimeQP << "\t\t pC[i] = pA[i] + pB[i] QueryPerformanceCounter mc" << endl; } int main() { setlocale(LC_ALL, ""); int n = 1500000; int* pA = (int*) malloc(sizeof(int)*n); int* pB = (int*) malloc(sizeof(int)*n); int* pC = (int*) malloc(sizeof(int)*n); for(int i = 0; i < n; ++i) { pA[i] = i; pB[i] = i; pC[i] = 0; } AddArrays( n, pA, pB, pC); free(pA); free(pB); free(pC); system("\npause"); return 0; } Прикреплённый файлCpuGpu.zip (2,25 Кбайт, скачиваний: 92) |
Сообщ.
#7
,
|
|
|
У меня:
timeGetTime: ≈10 мс GetTickCount: ≈15 мс, но иногда даёт и 0. QueryPer..: ≈10+eps Ничего странного не вижу. GetTickCount весьма грубая функция, поэтому когда там системный поток изменит её внутреннюю переменную - дело случая: Цитата \private\ntos\ex\i386\tickcnt.asm А timeGetTime и QueryPC несколько ответственнее подходят, потому у них и не прыгает разница. cPublicProc _NtGetTickCount, 0 cPublicFpo 0, 0 mov eax,dword ptr [_KeTickCount] mul dword ptr [_ExpTickCountMultiplier] shrd eax,edx,24 ; compute resultant tick count stdRET _NtGetTickCount stdENDP _NtGetTickCount |
Сообщ.
#8
,
|
|
|
Спасибо за ответ, понятно
|
Сообщ.
#9
,
|
|
|
Цитата Славян @ Ничего странного не вижу. GetTickCount весьма грубая функция, поэтому когда там системный поток изменит её внутреннюю переменную - дело случая: Системные тики и время изменяются (строго) по прерываниям системного таймера (имеющим наивысший приоритет). А "дело случая" заключается в том, в какой момент делается первый вызов GetTickCount - в начале этого интервала или в конце. Если в начале, то получается одно значение разности (возможно = 0, если измеряемый интервал меньше интервала таймера), а если в конце, то м.б. на 1 тик больше (можно получить 15 мс при реальной разнице в 1 мс и менее). PS: Повысить стабильность\предсказуемость результата можно путем вызова Sleep(1) перед первым вызовом GetTickCount. В этом случае ОС должна усыпить поток как минимум до начала следующего тика. Соотв-но и его пробуждение с большей вероятностью произойдет в начале интервала, а не в конце. А некоторая "странность" заключается в том, что timeGetTime работает с более высоким разрешением по сравнению с GetTickCount, хотя из описания timeGetTime и timeBeginPeriod следует, что разрешение timeGetTime зависит от установки timeBeginPeriod, которая в свою очередь задает интервал сис-таймера и соотв-но разрешение всех "обычных" функций ожидания, получения тиков и времени, и т.п. Причем в недалеком прошлом (по кр.мере в WinXP) так оно и было. |
Сообщ.
#10
,
|
|
|
На заметку присутствующим: между timeGetTime и QueryPerformanceCounter тоже есть небольшая разница/рассинхрон.
|