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

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

  1. Phuntik

    Phuntik New Member

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

    nop_ New Member

    Публикаций:
    0
    Регистрация:
    21 июн 2007
    Сообщения:
    61
    В таком случае нужено вычленять кусок кода минимального объема, на котором у тебя воспроизводится неверное поведение. Иначе остается только гадать.
     
  3. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    cppasm
    Прошу прощения, а ты вот без этого компилировал - #pragma optimize("", off) ? )
     
  4. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Да, из исходника удалил вообще, задавал опциями компилятора из командной строки.
    Ты попробуй добавь после этого ticksInUs = quad * 1e-6; вывод значения в консоль илди файл и посмотри разные они будут с разными опциями оптимизации или нет.
     
  5. Phuntik

    Phuntik New Member

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

    Вобщем, в пустом приложении создание этого класса проходит успешно. Блин, как это выловить теперь, ума не приложу.
    Может, влияние Qt? Никто с подобными конфликтами с Qt не сталкивался?

    Эх, будь здесь незанятый специалист с установленным Qt4 и VS2008, да немножко альтруист, да времени немного свободного, может, подсобил бы. Мне это не разгребсти.
     
  6. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    Вопрос-то не сильно важный, скомпилирую эту функцию с отключенной оптимизацией, просто интересно, почему так получается.
     
  7. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    Phuntik
    Удостоверься, что эта ф-ция не инлайнится в релизе (добавь к этой ф-ции __declspec(noinline)).
    Приведи полные листинги этой ф-ции в обоих режимах компиляции.
     
  8. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    У него скорее всего где-то память трётся, либо не инициализирована.
    Этот код в отдельном проекте правильно работает при любых опциях.
    Он и сам потом писал:
    Косяк в другом месте.
     
  9. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    Ведь начал правильно спрашивать и я подсказал, но куда-то вас всех не туда "унесло".
    В первом посте ты привел только часть дизассемблера - я и написал : приведи полный дизасм функции, чтобы можно было понять что врет. Ну и нарисовал бы по шагам что в counter пишется и откуда получается неправильное значение.
     
  10. Phuntik

    Phuntik New Member

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

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    valterg готов поспорить что код будет идентичный.
    Результат конкретно деления всегда правильный, он трётся где-то.
     
  12. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    Вот что происходит:
    Код (Text):
    1.                                                                                    counter             quad        ticksInUs
    2. Timer::Timer() {                                                               -4995072469926809587  not found   -4.8366978272229995e-026
    3. 0041CC80  push        esi                                                  
    4. 0041CC81  mov         esi,ecx
    5.     QueryPerformanceFrequency(&counter);
    6. 0041CC83  push        esi  
    7. 0041CC84  call        dword ptr [__imp__QueryPerformanceFrequency@4 (438050h)] 8971828998557458702                1.6649028232481585e-305
    8.     LONGLONG quad = counter.QuadPart;
    9.     ticksInUs = quad * 1e-6;
    10. 0041CC8A  fild        qword ptr [esi]
    11. }
    12. 0041CC8C  mov         eax,esi
    13. 0041CC8E  fmul        qword ptr [__real@3eb0c6f7a0b5ed8d (438B60h)]
    14. 0041CC94  fstp        qword ptr [esi+8]
    15. 0041CC97  pop         esi  
    16. 0041CC98  ret
    После вызова QueryPerformanceFrequency меняются counter и ticksInUs и дальше они не изменяют свои значения.
     
  13. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    Вот здесь:
    Код (Text):
    1. Timer::Timer() {
    2.     QueryPerformanceFrequency(&counter);
    3.     LONGLONG quad = counter.QuadPart;
    4.     ticksInUs = quad * 1e-6;
    5.     cout << ticksInUs;
    6. }
    отладчик показывает некорректное значение, а в консоль выводится то, что и должно быть. В остальных функциях на ticksInUs говорит, что символ не найден. Это нормально для включенной оптимизации?
    Короче, запутался я. Маловато опыта.
     
  14. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    При влюченной оптимизации в отладчик лучше не глядеть.
     
  15. W4FhLF

    W4FhLF New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2006
    Сообщения:
    1.050
    А если отключить для этих переменных оптимизацию? Поставь квалификатор volatile в объявлении переменных внутри метода и класса.

    т.е.:

    volatile LARGE_INTEGER counter;
    volatile double ticksInUs;

    и

    volatile LONGLONG quad;
     
  16. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    И нас запутываешь. В консоль правильно выводится ? Если правильно, то просто отладчик врет.
    А переменной нет, т.к. она не нужна - вычислили, выдали и забыли...
    А про трассировку в отладчике - я имел в виду режим чистого ассемблера(дизассемблера).
    Просто по командам пройтись. И смотреть не на имена переменных, а на стек FPU.
     
  17. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    W4FhLF
    С волатайлами то же самое.
    valterg
    Она должна быть нужна в другой функции :
    Код (Text):
    1. //  [11/4/2009 Sasha]
    2. void Timer::DelayUs(double us) {
    3.     static LONGLONG prevTicks = 0;
    4.     QueryPerformanceCounter(&counter);
    5.     LONGLONG ticks = (LONGLONG)(us * ticksInUs);                // Сколько тиков нужно пропустить
    6.     while ((counter.QuadPart - prevTicks) < ticks){
    7.         QueryPerformanceCounter(&counter);
    8.     }
    9.     prevTicks = counter.QuadPart;
    10. }
    , которая тоже используется.
    Вот про это я и говорил, когда говорил, что у меня недостаточно умений для этого (
     
  18. Phuntik

    Phuntik New Member

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

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    Ну если отладчик из студии - в окошке где регистры щелкаешь правой кнопкой мышки и включаешь Floating Point. Дизассемблер ты умешь делать - есть выбрать Step int, то будет по одной команде трассировать и в окне регисров красным показаны изменения. Только на call не деалай Step into, а то пойдешь отлаживать системные функции. Хотя студия может и не пустить...
    Если все вычисляется одинаково правильно, то придется делать New data break - отслеживать изменение памяти. Адрес ячейки можно из регистров посмотреть. Если про регистры непонятно, то нарисуй - подскажем... А лучше конечно ollydebug, хотя фиг его знает.
     
  20. Phuntik

    Phuntik New Member

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