Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник |
Коллекция курьезных вопросов из форумов
KOL и MCK |
KOL и MCK - Компактные программы на Delphi
Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / rsdn.org

 
Чтобы не потерять эту дискуссию, сделайте закладку « предыдущая ветвь | форум | следующая ветвь »

Оптимизация и Double


dmk ©   (14.01.17 16:01

Странное дело. Есть такой код:

var
 t: double;

t := (1 / 1000);

С включенной опцией компилятора Optimization получается число QNAN.
Без оптимизации все нормально.

Кто нибудь сталкивался? И как можно это дело обойти?
Delphi XE6.


rrrrr ©   (14.01.17 18:02[1]

1.0/1000.0


dmk ©   (14.01.17 20:28[2]

1 и 1000 целочисленные.


NoUser ©   (15.01.17 00:29[3]

как узнал, что там QNAN ? (32/64?)


dmk ©   (15.01.17 01:54[4]

Через FloatToStrF выводит строку NAN и в Watch List добавил переменную.


dmk ©   (15.01.17 01:54[5]

64


Германн ©   (15.01.17 03:12[6]


> dmk ©   (14.01.17 20:28) [2]
>
> 1 и 1000 целочисленные.

Это ты так считаешь. На самом деле что 1, что 1000 это константы неопределенного типа. Как их использует компилятор - знает только он.


NoUser ©   (15.01.17 03:14[7]

Ставь точку останова и показывай асм/регистры


dmk ©   (15.01.17 12:58[8]

Да с регистрами все в порядке. Сразу после расчета 0.001 получается. Сделал переменные глобальными — стало все в порядке, а так компилятор рушил локальные переменные, хотя и не должен.

Получается так:
1. f := 1/1000;
2. Какие-то другие расчеты
3. Вызов внешней процедуры
4. Тут происходит слет внутренних переменных.
5. Использование переменных невозможно из-за слетевшего значения

А не должно быть так вроде :(


NoUser ©   (15.01.17 17:35[9]

> 3. Вызов внешней процедуры
с этого момента поподробнее ))


dmk ©   (15.01.17 19:56[10]

Тут дело в оптимизации в общем. Когда она включена, то переменные по возможности хранятся в XMM-регистрах, а когда выключена в памяти. Отсюда и слет при внешнем вызове. У меня XMM-регистры используются.


dmk ©   (15.01.17 19:56[11]

Видимо недоработка компилятора.


NoUser ©   (15.01.17 23:11[12]

> У меня XMM-регистры используются.
ну-у, может и не только у тебя они используются?

Видимо тебе нужно узнать, как договорится об их совместном использовании.
(https://msdn.microsoft.com/ru-ru/library/zthk2dkh.aspx)


dmk ©   (16.01.17 01:27[13]

Да не, с передачей параметров у меня порядок. Какого черта компилятор переменные помещает в регистры?


NoUser ©   (16.01.17 01:41[14]

а как иначе процессору работать с переменными ?

++
(https://msdn.microsoft.com/ru-ru/library/9z1stfyw.aspx)


dmk ©   (16.01.17 13:50[15]

>а как иначе процессору работать с переменными ?

Процессор тут не при чем. Это компилятор распихивает переменные. В случае оптимизации в регистры. Без - в память. Отсюда и глюк.


NoUser ©   (16.01.17 15:32[16]


>  В случае оптимизации в регистры.

и глюк в том, что ты тоже используешь эти регистры (из асм кода) не сохранив/восстановив их значение?


dmk ©   (16.01.17 20:34[17]

Ну да. Именно так. Подстава от компилятора :)


dmk ©   (16.01.17 20:36[18]

У меня просто оптимизация никогда не включалась. По умолчанию она выключена.


Германн ©   (17.01.17 01:09[19]

Так кто кого подставил?


dmk ©   (17.01.17 01:29[20]

>Так кто кого подставил?
Компилятор меня. В хелпе про это нет ни слова.


Rouse_ ©   (17.01.17 18:48[21]

Вообще странно, я проверил на ХЕ4 и на последнм Берлине, не воспроизвелось (ХЕ6 нет)


dmk ©   (17.01.17 21:11[22]

Для меня это тоже странно.

Там такой код:
 //Единица на случай нулевой разницы
 if (gEndTime = gStartTime) then gEndTime := (gEndTime + 1);
 //Время использованное на отрисовку кадра в миллисекундах
 gUsedTime := (gEndTime - gStartTime);
 //Время использованное на отрисовку кадра в секундах
 gFrameTime := (gUsedTime / 1000);
 //Всего кадров отрисовано с момента сброса
 gTotalFrames := (gTotalFrames + 1);
 //Всего времени с момента сброса
 gTotalTime := (gTotalTime + gFrameTime);
 //Кадров в секунду с момента сброса
 gFPS := (gTotalFrames / gTotalTime);


Потом вызывается

//Рамка региона отсечения
sBmp.RectAA(Rgn.X, Rgn.Y, Rgn.W, Rgn.H, crWhite, 255, 128);


Внутри RectAA есть вызов

//Рисуем линию
FBlendScLine(lpDA, lpLen, dColor, dAlpha, dOpacity);


В линии (часть кода):
 //Формируем маски очистки из одной
 movdqu xmm6, PClearMask //Читаем общую маску очистки
 movdqu xmm8, xmm6 //дублируем
 movdqu xmm9, xmm6 //дублируем
 psrldq xmm8, 1 //xmm8 - Маска очистки 15-го байта
 psrldq xmm9, 15 //xmm9 - маска инверсии
 psrldq xmm6, 8 //в xmm6 маска очистки 7..0 байтов


В общем использую xmm на полную. После выход а из нее переменная приобретает вид QNAN вместо 0,001 как было до нее.

Где я накосячил?
Если сделать переменную глобальную - все в полном порядке.
Если выключить оптимизацию - все хорошо.
Поэтому вывод один - компилятор пихает локульную переменную в регистры.
И да стека у меня нет. Ничего не сохраняю. Там все 16 xmm-регистров используются.


dmk ©   (17.01.17 21:14[23]

МОгу полный код FBlendScLine на почту скинуть. Кормить не хочу халявщиков :)


Давно не заходил   (17.01.17 22:01[24]

In line with the x64 Application Binary Interface (ABI), the contents of the following registers must be preserved and restored within inline assembly functions: R12, R13, R14, R15, RDI, RSI, RBX, RBP, RSP, XMM4, XMM5, XMM6, XMM7, XMM8, XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, and XMM15.

http://docwiki.embarcadero.com/RADStudio/XE6/en/Using_Inline_Assembly_Code


dmk ©   (17.01.17 23:23[25]

Ну да, меня предупреждали :(


dmk ©   (17.01.17 23:23[26]

Спасибо!


версия для печати

Написать ответ

Ваше имя (регистрация  E-mail 







Разрешается использование тегов форматирования текста:
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)


Наверх

  Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо