Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Почему компилятор выкидывает цикл?  (Прочитано 5519 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Tuborg
Команда клуба

ee
Offline Offline

« : 15-01-2004 13:36 » 

CompileTarget: DOS
Compiler: BC 3
 Есть некая функция реализующая временную задержку в проге, в одном варианте (Вар. I) оно отрабатывает заданные 100 секунд, а в другом (Вар. II) оно вылетает сразу. В чём здесь может быть проблема? Все оптимизации отключены. Может есть какая нибудь спасительная деректива прекомпиляции?
-------------
Вар. I
Timer::TimeDelay(DWord mcs){
  DWord beginTime=0, delta=0;
  beginTime=getTimeValue();
  while(delta<mcs){
    delta=getTimeValue()-beginTime;
    printf("\n");
  }
}

Вар. II
Timer::TimeDelay(DWord mcs){
  DWord beginTime=0, delta=0;
  beginTime=getTimeValue();
  while(delta<mcs){
    delta=getTimeValue()-beginTime;
  }
}
Записан
ixania
Гость
« Ответ #1 : 15-01-2004 13:55 » 

Вопервых поисание getTimeValue() нигде не могу найти, может это чтото твое.
Во вторых в первом варианте printf("\n"); тож обавляет задержку, т.к. вывод на экран требует времени.
Записан
Tuborg
Команда клуба

ee
Offline Offline

« Ответ #2 : 15-01-2004 13:57 » 

1. getTimeValue() - моя функция читающая значение счётчика таймера в микросекундах.
2. Вариант с printf("\n") не может выполнятся в 100 раз медленее (100 секунд)
Записан
ixania
Гость
« Ответ #3 : 15-01-2004 14:04 » 

И как ты читаешь с  getTimeValue() в микросекундах, как реализована? т.к time (0) выдает в секундах как я помню.
Записан
Serega
Гость
« Ответ #4 : 15-01-2004 17:02 » 

обьявляй переменные как volatile
getTimeValue это макрос, просто адрес памяти куда дос записывает количество тиков (адрес могу впомнить)
компилятор видит что в куске кода происходит чтение из памяти, но нет записи по этому адресу, поэтому цикл с многократным чтением и оптимизируется, ты глянь что он на асме выдает
volatile указывает компилятору что значение переменной может меняться вне программы (потока)
Записан
ixania
Гость
« Ответ #5 : 15-01-2004 18:31 » 

А чем sleep плох?
Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #6 : 15-01-2004 19:23 » 

volatile - это говорит только то, что значение будет браться из памяти - у Рихтера прочел. А пустой цикл оптимизируется - вовсе не причем там тип макроса ИМХО конечно.
Просто в цикле сделать надо что-то типа простейшей операции. i=i<<1;
и все будет работать.
Записан

А птичку нашу прошу не обижать!!!
ixania
Гость
« Ответ #7 : 15-01-2004 20:12 » 

Timer::TimeDelay(DWord mcs){
     sleep (mcs);  
}

  Вот такой я вот  зачем заново велосипед изобретать?
Записан
Alf
Гость
« Ответ #8 : 15-01-2004 23:12 » 

Цитата: Гром
volatile - это говорит только то, что значение будет браться из памяти - у Рихтера прочел. А пустой цикл оптимизируется - вовсе не причем там тип макроса ИМХО конечно.
Просто в цикле сделать надо что-то типа простейшей операции. i=i<<1;
и все будет работать.
Думаю, что насчет оптимизации ты абсолютно прав. А вот насчет простейшей операции - не уверен.
Был такой случай в практике. В конце 80-х попала в мои руки мини-ЭВМ VAX-11/725 (если кто застал те времена, помнят, что это была надежда Пентагона, очень удачная серия супермини-ЭВМ). Захотелось самому определить ее быстродействие. Для этого написал что-то вроде:
Код:
long k = 0;
for )long i = 0; i < 10000000; i++:
  k = k + 1;

(на самом деле писано это было на FORTRAN77 или на Pascal, но суть не в этом). Запустил, засек время - выполняется около секунды. Ладно, думаю, в принципе возможно. Увеличил предел цикла в 10 раз - то же самое. Еще в 10 раз - то же самое :!:
Я точно знал, что миллиард коротких сложений в секунду агрегат делать не может. Стал разбираться с кодом. Оказалось, что умный компилятор понял, что значение k не используется дальше, и не стал его считать вовсе  Улыбаюсь
Ладно, решил немного схитрить. Поставил в конце программы печать значения k, чтобы заставить комп его вычислить. Запускаю - то же самое. Лезу в код. Оказалось, что оптимизатор сообразил, что незачем 10000000 раз складывать по единице, и заменил все это на
Код:
k = 10000000

а затем напечатал значение. Аналогичные простейшие уловки тоже не смогли сбить его с толку. Пришлось выдумать выражение посложнее, чтобы он не мог заранее его посчитать на этапе компиляции.
А теперь прикиньте, что с тех пор минуло лет 15, наверное... Думаю, что творцы компиляторов с тех пор вряд ли разучились оптимизировать, тем более такие элементарные вещи. Если значение delta нигде дальше не используется, скорее всего, цикл просто будет выброшен из программы.
Записан
Serega
Гость
« Ответ #9 : 16-01-2004 07:52 » 

Гром, меня не переспоришь Отлично
Вот кусок из Страуструпа:
A volatile specifier is a hint to a compiler that an object may change its value in ways not specified by the language so that aggressive optimizations must be avoided. For example, a real time clock might be declared:

extern const volatile clock;

Two successive reads of clock might give different results.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines