Как начать отладку числового кода, когда NaN появляются только при компиляции с оптимизациями?

Каковы общие стратегии для начала отладки числового кода, когда:

  • код, скомпилированный с агрессивными флагами оптимизации, производит случайные NaN и Inf на выходе
  • код, скомпилированный с -g (что подразумевает -O0) для работы с отладчиком, больше не производит NaN и Inf?

В этом случае я работал с компилятором Portland Group C ++, pgCC, и использовал параметры оптимизации.

-w -fast -O3 -Mipa=fast -Mfprelaxed -Minline=levels:10

а потом просто

-w -g

для отладочной версии. Но я уверен, что похожая ситуация может произойти и с g++.

РЕДАКТИРОВАТЬ: Добавление операторов печати - не очень привлекательный вариант, так как код написан не мной, это несколько тысяч строк, и я не знаю, чтобы сузить поиск; NaN могут возникать практически откуда угодно.


person Sampo Smolander    schedule 13.04.2012    source источник
comment
Можете ли вы добавить отчеты для печати?   -  person Oliver Charlesworth    schedule 13.04.2012
comment
Если правильность важнее скорости, держитесь подальше от оптимизаций, которые вы не контролируете.   -  person Alexey Frunze    schedule 13.04.2012
comment
Алекс: Было бы неплохо найти подозрительные строки в исходном коде, чтобы иметь возможность взглянуть на них и решить, кажутся ли они правильными или нет.   -  person Sampo Smolander    schedule 13.04.2012
comment
Подозрительны не строчки, а тот факт, что, когда у вас ограниченная числовая точность, перестают работать обычные математические законы коммутативности и распределительности, а когда компилятор переупорядочивает операции по своей прихоти в предположении, что законы все еще работают, вы начинаете странно Результаты.   -  person Alexey Frunze    schedule 13.04.2012


Ответы (3)


Я бы попытался посмотреть, можете ли вы включить исключения с плавающей запятой как здесь, затем см. если есть исключение, выброшенное из некоторой сигнальной нан. Вероятно, в вашем компиляторе есть какой-то флаг компилятора, чтобы включить эти исключения.

Если не считать этого, я бы выполнял бинарный поиск вручную. То есть напишите функцию, которая выгружает все переменные. Затем разделите программу пополам, но не по строкам кода, а по тому, что на самом деле выполняется, и изолируйте ее. Другими словами, закатайте рукава и приступайте к делу.

Изменить: это может не относиться к вашему случаю, поскольку ссылка, которую я вам дал, была очень специфичной для Win32. Но, возможно, это даст вам некоторые зацепки. Или вы можете попробовать код на бесплатном компиляторе MS?

person Chris A.    schedule 13.04.2012
comment
+1: Wolf Fence на Аляске (также известный как бинарный поиск) очень эффективен при правильном использовании. 20 проходов уменьшат объем вашей проблемы в 2 ^ 20 раз, или более чем в 1 000 000 раз. Это особенно полезно при решении проблем Black Box®, класса, который включает оптимизирующие компиляторы. - person Peter Rowell; 14.04.2012

Компиляторы Portland Group предоставляют некоторые параметры, сопровождающие директиву -Mfprelaxed; Я бы попытался установить их один за другим и посмотреть, какие из них имеют значение. Вы можете просто удалить эту директиву из своей компиляции.

person High Performance Mark    schedule 13.04.2012

Хочу отметить, что в случае g ++ флаг -g не подавляет оптимизацию (то есть не подразумевает -O0). Оптимизированный исполняемый файл, содержащий отладочную информацию, труднее отлаживать, но, безусловно, это возможно.

person jmbr    schedule 13.04.2012