У меня действительно странная ошибка, которую я потратил несколько дней, пытаясь выяснить, и поэтому теперь я хочу посмотреть, есть ли у кого-нибудь комментарии, которые помогут мне понять, что происходит.
Некоторый фон. Я работаю над программным проектом, который включает добавление расширений C ++ в Python 2.7.1 с использованием Boost 1.45, поэтому весь мой код выполняется через интерпретатор Python. Недавно я внес изменения в код, который нарушил один из наших регрессионных тестов. Этот регрессионный тест, вероятно, слишком чувствителен к численным колебаниям (например, на разных машинах), поэтому я должен это исправить. Однако, поскольку эта регрессия нарушается на том же компьютере / компиляторе, который дал исходные результаты регрессии, я проследил разницу в результатах с этим фрагментом числового кода (который достоверно не связан с измененным кодом):
c[3] = 0.25 * (-3 * df[i-1] - 23 * df[i] - 13 * df[i+1] - df[i+2]
- 12 * f[i-1] - 12 * f[i] + 20 * f[i+1] + 4 * f[i+2]);
printf("%2li %23a : %23a %23a %23a %23a : %23a %23a %23a %23a\n",i,
c[3],
df[i-1],df[i],df[i+1],df[i+2],f[i-1],f[i],f[i+1],f[i+2]);
, который строит некоторые числовые таблицы. Обратите внимание, что:
- % отпечатков обеспечивает точное представление ascii
- Левая часть (lhs) - c [3], а rhs - остальные 8 значений.
- Вывод ниже был для значений i, которые были далеки от границ f, df
- этот код существует в цикле над i, который сам вложил несколько слоев (поэтому я не могу представить отдельный случай, чтобы воспроизвести это).
Итак, я клонировал дерево исходных текстов, и единственное различие между двумя исполняемыми файлами, которые я компилирую, состоит в том, что клон содержит некоторый дополнительный код, который даже не выполняется в этом тесте. Это заставляет меня подозревать, что это должно быть проблема с памятью, поскольку единственная разница должна заключаться в том, где код существует в памяти ... В любом случае, когда я запускаю два исполняемых файла, вот разница в том, что они производят:
diff new.out old.out
655,656c655,656
< 6 -0x1.7c2a5a75fc046p-10 : 0x0p+0 0x0p+0 0x0p+0 -0x1.75eee7aa9b8ddp-7 : 0x1.304ec13281eccp-4 0x1.304ec13281eccp-4 0x1.304ec13281eccp-4 0x1.1eaea08b55205p-4
< 7 -0x1.a18f0b3a3eb8p-10 : 0x0p+0 0x0p+0 -0x1.75eee7aa9b8ddp-7 -0x1.a4acc49fef001p-6 : 0x1.304ec13281eccp-4 0x1.304ec13281eccp-4 0x1.1eaea08b55205p-4 0x1.9f6a9bc4559cdp-5
---
> 6 -0x1.7c2a5a75fc006p-10 : 0x0p+0 0x0p+0 0x0p+0 -0x1.75eee7aa9b8ddp-7 : 0x1.304ec13281eccp-4 0x1.304ec13281eccp-4 0x1.304ec13281eccp-4 0x1.1eaea08b55205p-4
> 7 -0x1.a18f0b3a3ec5cp-10 : 0x0p+0 0x0p+0 -0x1.75eee7aa9b8ddp-7 -0x1.a4acc49fef001p-6 : 0x1.304ec13281eccp-4 0x1.304ec13281eccp-4 0x1.1eaea08b55205p-4 0x1.9f6a9bc4559cdp-5
<more output truncated>
Вы можете видеть, что значение в c [3] слегка отличается, хотя ни одно из значений rhs не отличается. Таким образом, некоторые идентичные данные приводят к разным результатам. Я попытался упростить выражение rhs, но любое изменение, которое я делаю, устраняет разницу. Если я напечатаю & c [3], то разница исчезнет. Если я работаю на двух разных машинах (linux, osx), к которым у меня есть доступ, разницы нет. Вот что я уже пробовал:
- valgrind (сообщалось о многочисленных проблемах в python, но ничего в моем коде и ничего серьезного)
- -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_ASSERT -D_GLIBCXX_DEBUG_PEDASSERT -D_GLIBCXX_DEBUG_VERIFY (но ничего не утверждается)
- -fno-strict-aliasing (но я получаю псевдонимы предупреждений компиляции из кода повышения)
Я попытался переключиться с gcc 4.1.2 на gcc 4.5.2 на машине, на которой возникла проблема, и эта конкретная, изолированная разница исчезла (но регрессия все равно не удалась, поэтому давайте предположим, что это другая проблема).
Могу ли я что-нибудь сделать, чтобы изолировать проблему дальше? Для дальнейшего использования, есть ли способ быстрее проанализировать или понять проблему такого рода? Например, учитывая моё описание изменения lhs, хотя rhs нет, что бы вы сделали вывод?
EDIT:
Проблема была полностью из-за -ffast-math
.