Разный результат деления в debug и release режимах

Тема в разделе "LANGS.C", создана пользователем Phuntik, 4 ноя 2009.

  1. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    Добрый день.
    Имеется код:
    Код (Text):
    1. Timer::Timer() {
    2.     LARGE_INTEGER counter;
    3.     QueryPerformanceFrequency(&counter);
    4.     ticksInUs = (double)counter.QuadPart / (double)1e6;
    5. }
    В дебаге получается то, что надо - 3.5. Вот листинг:
    Код (Text):
    1.     ticksInUs = (double)counter.QuadPart / (double)1e6;
    2. 0041F813  fild        qword ptr [counter]
    3. 0041F816  fdiv        qword ptr [__real@412e848000000000 (4420A8h)]
    4. 0041F81C  mov         ecx,dword ptr [this]
    5. 0041F81F  fstp        qword ptr [ecx]
    6. }
    7. 0041F821  mov         eax,dword ptr [this]
    8. 0041F824  mov         esp,ebp
    9. 0041F826  pop         ebp  
    10. 0041F827  ret
    В релизе получается совершенно левое число с порядком +297. Вот листинг:
    Код (Text):
    1.     ticksInUs = (double)counter.QuadPart / (double)1e6;
    2. 0041C841  fild        qword ptr [esp+4]
    3. }
    4. 0041C845  mov         eax,esi
    5. 0041C847  fdiv        qword ptr [__real@412e848000000000 (437DE0h)]
    6. 0041C84D  fstp        qword ptr [esi]
    7. 0041C84F  pop         esi  
    8. 0041C850  add         esp,8
    9. 0041C853  ret
    Чем это может быть вызвано, подскажите, куда копать, у меня нет никаких идей.
     
  2. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    Ой простите, я имел ввиду без оптимизации и с ней. Остальные параметры одинаковы. Релиз, в принципе, с отладочной информацией.
     
  3. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    Ну так посмотри строчки перед этим. Видимо оптимизация с багом. Например, счетчик заранее заброшен в [esp+4] и читается мусор. Либо конструкцию (double)counter.QuadPart неправильно проинтерпретировало.
     
  4. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    Мне тоже кажется, что оптимизация с багом. Так что делать-то? В отладчике в таком участке:
    Код (Text):
    1. //  [11/3/2009 Sasha]
    2. Timer::Timer() {
    3.     QueryPerformanceFrequency(&counter);
    4.     LONGLONG quad = counter.QuadPart;
    5.     ticksInUs = quad / 1e6;
    6. }
    значение ticksInUs вообще не изменяется, а в другом методе, где оно используется, вообще не определено.
    Хорошенькая оптимизация.
    Если бы я знал, как ботву эту разгрести, не обращался бы сюда. А есть вообще возможность указать, что некоторые участи кода оптимизировать не нужно?
     
  5. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    Отлючил оптимизацию директивой pragma optimize, а жаль, конечно.
     
  6. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Phuntik
    Оптимизатор корёжит от алгоритмической антиоптимизации в исходном коде :))
    Замени деление на 1e6 умножением на 1e-6 ;)
     
  7. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    Век живи, век учись) Никогда бы не подумал. А почему это антиоптимизация?)
     
  8. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Деление выполняется значительно медленнее умножения и везде где возможно его надо заменять, иногда компилятор сам это делает но в таких случаях где FPU используется не справляется.
     
  9. comrade

    comrade Константин Ёпрст

    Публикаций:
    0
    Регистрация:
    16 сен 2002
    Сообщения:
    232
    Адрес:
    Russian Federation
    Почитай про разницу между /fp:precise и /fp:fast. Мне кажется у тебя это по разному стоит в debug и releasе билдах:

    http://msdn.microsoft.com/en-us/library/e7s85ffb.aspx
     
  10. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Phuntik

    Какой компилятор-то?
     
  11. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    Y_Mur
    Не догоняю. Ну медленнее, и что? Почему неправильно? Поясните глупому или ссылочку, пожалуйста.
    comrade
    Билд один - release. Включена отладочная информация, и лишь в настройках проекта - в одном случае - без оптимизации, а в другом - оптимизация по скорости.

    _DEN_
    А да, совсем забыл VS2008 + SP1. Вот только не уверен, что сервиспак установился как нужно.
     
  12. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Phuntik
    Не неправильно, а неоптимально - у тебя же оптимизатор глючит :)) Кстати с умножением-то заработало?
     
  13. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    я наверно совсем тупой, но логика кода одинакова.
     
  14. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    Так это же один и тот же код, естественно.

    Y_Mur
    Нет.
     
  15. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    ну раз код один и тот же, то откуда могуть быть баги?
     
  16. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Я говорю про ассемблерный листинг.
    Баг значит в другом месте.
    Проверил у себя - код примерно такой же, багов нет.
     
  17. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    Код (Text):
    1. #ifndef _TIMER_H_
    2. #define _TIMER_H_
    3.  
    4. #include <windows.h>
    5.  
    6. class Timer
    7. {
    8. public:
    9.     Timer();
    10.     void DelayUs(double us);       // Вызов этой функции вызывает задержку на заданное значение микросекунд после предыдущего вызова этой функции
    11.  
    12.     void Start(double us);    // Можно запустить таймер на us миллисекунд
    13.     bool IsRun();             // и потом проверять, работает ли он ещё или уже вышел
    14. private:
    15.     LARGE_INTEGER counter;
    16.     double ticksInUs;
    17.  
    18.     LONGLONG startTimerInTicks;    // Время запуска таймера в тиках
    19.     LONGLONG timeTimerInTicks;     // Количество тиков, через которое таймер должен закончить работу
    20. };
    21.  
    22. #endif
    Код (Text):
    1. // 18.02.2009
    2.  
    3. #include "timer.h"
    4. #include <fstream>
    5.  
    6. using namespace std;
    7.  
    8. #pragma optimize("", off)
    9.  
    10. //  [11/3/2009 Sasha]
    11. Timer::Timer() {
    12.     QueryPerformanceFrequency(&counter);
    13.     LONGLONG quad = counter.QuadPart;
    14.     ticksInUs = quad * 1e-6;
    15. }
    16.  
    17. //  [11/4/2009 Sasha]
    18. void Timer::DelayUs(double us) {
    19.     static LONGLONG prevTicks = 0;
    20.     QueryPerformanceCounter(&counter);
    21.     LONGLONG ticks = (LONGLONG)(us * ticksInUs);                // Сколько тиков нужно пропустить
    22.     while ((counter.QuadPart - prevTicks) < ticks){
    23.         QueryPerformanceCounter(&counter);
    24.     }
    25.     prevTicks = counter.QuadPart;
    26. }
    27.  
    28. //  [11/4/2009 Sasha]
    29. void Timer::Start(double us) {
    30.     QueryPerformanceCounter(&counter);
    31.     startTimerInTicks = counter.QuadPart;
    32.     timeTimerInTicks = us * ticksInUs;
    33. }
    34.  
    35. //  [11/4/2009 Sasha]
    36. bool Timer::IsRun() {
    37.     QueryPerformanceCounter(&counter);
    38.     return ((counter.QuadPart - startTimerInTicks) > timeTimerInTicks) ? false : true;
    39. }
    n0nameВот класс целиком. Проверь, пожалуйста, если можно.
     
  18. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    VC++ 6.0 SP3, Intel C++ 10.1, VS 2008 Express - что с оптимизацией, что без результат одинаковый.
     
  19. nop_

    nop_ New Member

    Публикаций:
    0
    Регистрация:
    21 июн 2007
    Сообщения:
    61
    Я правильно понимаю что факт наличия "бага" подтверждает _только_ отладчиком?
     
  20. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    cppasmСпасибо.

    Глюк какой-то. Программа достаточно объёмная, остальное работает. Может быть, как-то связано с пресловутым выравниванием, как в старых версиях VS бывало?