LINUX.ORG.RU

gcc Ofast: баг или фича?

 , , ,


0

2

Столкнулся с тем, что добавление обычного printf меняет результат работы программы.

int3 cell;
for(cell.x = 0; cell.x < cells.x; ++cell.x)
for(cell.y = 0; cell.y < cells.y; ++cell.y)
for(cell.z = 0; cell.z < cells.z; ++cell.z)
{
    int id = cell.x*cells.y*cells.z + cell.y*cells.z + cell.z;
    //printf("%d\n", id);
    float3 moment = moments_ram_raw.get(id);
    ...
}

Эти moment потом записываются в другую область памяти, откуда сохраняются на диск в бинарный формат. Так вот, если раскомментировать printf, то бинарный файл изменится. Выяснилось, что виновик — ключ -Ofast. Замена уровня оптимизации на -O3 решила проблему.

Тем не менее, стоит ли копать дальше, чтобы это зарепортить в багтрекер gcc, или это нормальное поведение для -Ofast?

Версия компилятора gcc version 6.3.0 20170516 (Debian 6.3.0-18)

UPD: Ошибся разделом, перенесите в Development, пожалуйста

Перемещено beastie из desktop

-Ofast включает -ffast-math, получается погрешность, которая и меняет результат.

anonymous ()
Ответ на: комментарий от anonymous

На этот -ffast-math есть какие-то публичные спецификации?

Crocodoom ★★ ()

У тебя случаем int не переполняется?

i-rinat ★★★★★ ()
Ответ на: комментарий от Crocodoom

This option is not turned on by any -O option besides -Ofast since it can result in incorrect output for programs that depend on an exact implementation of IEEE or ISO rules/specifications for math functions. It may, however, yield faster code for programs that do not require the guarantees of these specifications.

ССЗБ, в общем :)

joy4eg ★★★★★ ()

А полностью рабочий пример? Вообще -Ofast включает опасные оптимизации и может менять поведение программы:

-Ofast enables all -O3 optimizations. It also enables optimizations that are not valid for all standard-compliant programs. It turns on -ffast-math and the Fortran-specific -fstack-arrays, unless -fmax-stack-var-size is specified, and -fno-protect-parens.

Т.е. потенциально он мог немного перемешать LD/ST операции (или что там у интелей), а вызов функции printf этому помешал. Но это не точно.

alexanius ()
Ответ на: комментарий от Crocodoom

Тогда нужно смотреть в сгенерированный код. Objdump в помощь.

i-rinat ★★★★★ ()

Тесты писать нужно, чтобы не приходилось бинари диффить :)

halz ()
Ответ на: комментарий от halz

Вообще-то это и был тест, который успешно провалился (иначе бы не было этой темы). Предложите другой вариант, я рассмотрю.

Crocodoom ★★ ()
Ответ на: комментарий от alexanius

Ну в общем понятно, тогда дальше копать не буду. Спасибо всем отписавшимся.

Crocodoom ★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.