Недавно мы начали видеть, что единичные тесты терпят неудачу на нашей машине сборки (некоторые численные вычисления вышли из толерантности). По результатам расследования мы обнаружили, что некоторые из наших разработчиков не смогли воспроизвести отказ теста. Чтобы сократить длинную историю, мы в конечном итоге отследили проблему до того, что, по-видимому, было ошибкой округления, но эта ошибка возникала только при сборке x64 на последних чипах Haswell (к которым недавно был добавлен наш сервер сборки). Мы сузили его и вытащили один расчет из одного из наших тестов:
#include "stdafx.h"
#include <cmath>
int _tmain(int argc, _TCHAR* argv[])
{
double rate = 0.0021627412080263146;
double T = 4.0246575342465754;
double res = exp(-rate * T);
printf("%0.20e\n", res);
return 0;
}
Когда мы скомпилируем этот x64 в VS2013 (с переключателями компилятора по умолчанию, включая /fp:precise
), он дает разные результаты на чипе Sandy Bridge и более новом чипе Haswell. Разница заключается в 15-й значащей цифре, которая, как мне кажется, находится за пределами машины epsilon для двойного использования на обеих машинах).
Если мы скомпилируем тот же код в VS2010 или VS2012 (или, кстати, VS2013 x86), мы получим тот же ответ на оба чипа.
В последние несколько лет мы прошли через многие версии Visual Studio и множество различных чипов Intel для тестирования, и никто не может вспомнить, что нам когда-либо приходилось корректировать наши ожидания тестирования регрессии на основе различных ошибок округления между фишками.
Это, очевидно, привело к игре бит-моль между разработчиками с более старым и новым оборудованием в отношении того, что должно быть ожиданием тестов...
Есть ли в VS2013 параметр компилятора, который нам нужно использовать, чтобы как-то смягчить несоответствие?
Обновление:
Results on Sandy Bridge developer PC:
VS2010-compiled-x64: 9.91333479983898980000e-001
VS2012-compiled-x64: 9.91333479983898980000e-001
VS2013-compiled-x64: 9.91333479983898980000e-001
Results on Haswell build server:
VS2010-compiled-x64: 9.91333479983898980000e-001
VS2012-compiled-x64: 9.91333479983898980000e-001
VS2013-compiled-x64: 9.91333479983899090000e-001
Update:
Я использовал procexp для захвата списка DLL, загруженных в тестовую программу.
Sandy Bridge developer PC:
apisetschema.dll
ConsoleApplication8.exe
kernel32.dll
KernelBase.dll
locale.nls
msvcr120.dll
ntdll.dll
Haswell build server:
ConsoleApplication8.exe
kernel32.dll
KernelBase.dll
locale.nls
msvcr120.dll
ntdll.dll