Добрый день. Имеется код: Code (Text): Timer::Timer() { LARGE_INTEGER counter; QueryPerformanceFrequency(&counter); ticksInUs = (double)counter.QuadPart / (double)1e6; } В дебаге получается то, что надо - 3.5. Вот листинг: Code (Text): ticksInUs = (double)counter.QuadPart / (double)1e6; 0041F813 fild qword ptr [counter] 0041F816 fdiv qword ptr [__real@412e848000000000 (4420A8h)] 0041F81C mov ecx,dword ptr [this] 0041F81F fstp qword ptr [ecx] } 0041F821 mov eax,dword ptr [this] 0041F824 mov esp,ebp 0041F826 pop ebp 0041F827 ret В релизе получается совершенно левое число с порядком +297. Вот листинг: Code (Text): ticksInUs = (double)counter.QuadPart / (double)1e6; 0041C841 fild qword ptr [esp+4] } 0041C845 mov eax,esi 0041C847 fdiv qword ptr [__real@412e848000000000 (437DE0h)] 0041C84D fstp qword ptr [esi] 0041C84F pop esi 0041C850 add esp,8 0041C853 ret Чем это может быть вызвано, подскажите, куда копать, у меня нет никаких идей.
Ой простите, я имел ввиду без оптимизации и с ней. Остальные параметры одинаковы. Релиз, в принципе, с отладочной информацией.
Ну так посмотри строчки перед этим. Видимо оптимизация с багом. Например, счетчик заранее заброшен в [esp+4] и читается мусор. Либо конструкцию (double)counter.QuadPart неправильно проинтерпретировало.
Мне тоже кажется, что оптимизация с багом. Так что делать-то? В отладчике в таком участке: Code (Text): // [11/3/2009 Sasha] Timer::Timer() { QueryPerformanceFrequency(&counter); LONGLONG quad = counter.QuadPart; ticksInUs = quad / 1e6; } значение ticksInUs вообще не изменяется, а в другом методе, где оно используется, вообще не определено. Хорошенькая оптимизация. Если бы я знал, как ботву эту разгрести, не обращался бы сюда. А есть вообще возможность указать, что некоторые участи кода оптимизировать не нужно?
Phuntik Оптимизатор корёжит от алгоритмической антиоптимизации в исходном коде ) Замени деление на 1e6 умножением на 1e-6
Деление выполняется значительно медленнее умножения и везде где возможно его надо заменять, иногда компилятор сам это делает но в таких случаях где FPU используется не справляется.
Почитай про разницу между /fp:precise и /fp:fast. Мне кажется у тебя это по разному стоит в debug и releasе билдах: http://msdn.microsoft.com/en-us/library/e7s85ffb.aspx
Y_Mur Не догоняю. Ну медленнее, и что? Почему неправильно? Поясните глупому или ссылочку, пожалуйста. comrade Билд один - release. Включена отладочная информация, и лишь в настройках проекта - в одном случае - без оптимизации, а в другом - оптимизация по скорости. _DEN_ А да, совсем забыл VS2008 + SP1. Вот только не уверен, что сервиспак установился как нужно.
Phuntik Не неправильно, а неоптимально - у тебя же оптимизатор глючит ) Кстати с умножением-то заработало?
Я говорю про ассемблерный листинг. Баг значит в другом месте. Проверил у себя - код примерно такой же, багов нет.
Code (Text): #ifndef _TIMER_H_ #define _TIMER_H_ #include <windows.h> class Timer { public: Timer(); void DelayUs(double us); // Вызов этой функции вызывает задержку на заданное значение микросекунд после предыдущего вызова этой функции void Start(double us); // Можно запустить таймер на us миллисекунд bool IsRun(); // и потом проверять, работает ли он ещё или уже вышел private: LARGE_INTEGER counter; double ticksInUs; LONGLONG startTimerInTicks; // Время запуска таймера в тиках LONGLONG timeTimerInTicks; // Количество тиков, через которое таймер должен закончить работу }; #endif Code (Text): // 18.02.2009 #include "timer.h" #include <fstream> using namespace std; #pragma optimize("", off) // [11/3/2009 Sasha] Timer::Timer() { QueryPerformanceFrequency(&counter); LONGLONG quad = counter.QuadPart; ticksInUs = quad * 1e-6; } // [11/4/2009 Sasha] void Timer::DelayUs(double us) { static LONGLONG prevTicks = 0; QueryPerformanceCounter(&counter); LONGLONG ticks = (LONGLONG)(us * ticksInUs); // Сколько тиков нужно пропустить while ((counter.QuadPart - prevTicks) < ticks){ QueryPerformanceCounter(&counter); } prevTicks = counter.QuadPart; } // [11/4/2009 Sasha] void Timer::Start(double us) { QueryPerformanceCounter(&counter); startTimerInTicks = counter.QuadPart; timeTimerInTicks = us * ticksInUs; } // [11/4/2009 Sasha] bool Timer::IsRun() { QueryPerformanceCounter(&counter); return ((counter.QuadPart - startTimerInTicks) > timeTimerInTicks) ? false : true; } n0nameВот класс целиком. Проверь, пожалуйста, если можно.
cppasmСпасибо. Глюк какой-то. Программа достаточно объёмная, остальное работает. Может быть, как-то связано с пресловутым выравниванием, как в старых версиях VS бывало?