[sisyphus] Странности при переходе объединении двух целых в вещественное на x86_64

Kirill A. Shutemov kirill на shutemov.name
Чт Авг 6 22:12:29 MSD 2009


2009/8/5 Roman Savochenko <rom_as at diyaorg.dp.ua>:
> Приветствую Всех
>
> Имеется некая целевая задачка собрать из двух 16-разрядных целых
> вещественное (float), 32 разряда.
> Казалось-бы тривиальная задача, которая решается кодом типа
> int w1 = 62915, w2 = 16456;
> ui32 vl = ((w2&0xffff)<<16) | w1&0xffff;
> //sleep(1);
> printf("TEST 00: %f\n",*(float*)&vl);
>
> И как ожидалось на x86_32 он работает корректно при различной нагрузке.
> А вот на x86_64 замечается ситуация когда вместо 3.14 получаем ноль.
> Причём в тестовой программке с единственным потоком всё работает нормально,
> а на высоконагруженном процессе с десятками потоков, из которых около пяти
> работают с периодом 5мс. устойчиво получатся 0.
> Если раскомментирую sleep, то получаю номальный результат 3.14.
>
> Кто нибуть может такое поведение объяснить?

Похоже, вы нарушили strict aliasing. Попробуйте собрать с -Wstrict-aliasing=2.
Если будет ругаться, то это наверно оно(см. оговорку в мане насчёт этой опции).

Нарушение strict aliasing может сломать некоторые оптимизации. Два выхода --
или собрать с -fno-strict-aliasing или переписать код корректней.


Подробная информация о списке рассылки Sisyphus