Причина разницы вывода в 1 бит между выводом скомпилированного кода Linux и gcc и скомпилированным выводом MS-VS2008?
У меня есть библиотека видеодекодера Theora и приложение, скомпилированное с использованием VS-2008 для Windows(архитектура Intel x86). Я использую эту настройку для декодирования потоков битов theora (*. Ogg). Исходный код для этой библиотеки декодера используется из исходного пакета FFMPEG v0.5 с некоторыми изменениями, чтобы он компилировался в комбинации windows-VS-2008.
Теперь, когда я декодирую тот же поток битов theora, используя приложение ffmpeg(V0.5) на linux(архитектура Intel x86), которое я создал с помощью gcc, и получаю некоторый декодированный выходной файл yuv, этот выходной файл имеет разницу в 1 бит с выходными данными, полученными из Настройка Windows-VS2008, и это тоже для нескольких байтов выходного файла, не все. Я ожидал, что 2 выхода будут соответствовать битам.
Я сомневаюсь в следующих факторах:
a.) Некоторое несоответствие типов данных между двумя компиляторами gcc и MS-VS2008?
b.) Я убедился, что в коде не используются никакие математические функции библиотеки времени выполнения, такие как log, pow, exp, cos и т. д., но все же в моем коде есть некоторые операции, такие как (a+b+c)/3.Could это будет проблемой?
Реализация этого "деления на три" или любого другого числа может отличаться в двух установках.
в.) Какие-то эффекты округления / усечения происходят по-другому?
d.) Могу ли я пропустить какой-либо макрос, который присутствует в Linux в качестве опции makefile / configure, которого нет в настройках Windows?
Но я не могу сузить проблему и исправить ее.
1.) Являются ли мои сомнения выше обоснованными, или могут быть какие-либо другие проблемы, которые могут вызвать эти 1-битные различия в выходных данных, создаваемых этими двумя различными установками.
2.) Как мне отладить и исправить это?
Я предполагаю, что этот сценарий различий в выходных данных между установкой linux-gcc и компиляторами Windows MS может быть верным даже для любого универсального кода (не обязательно характерного для моего случая приложения для декодирования видео)
Любые указатели будут полезны в этом отношении.
Спасибо,
-ОБЪЯВЛЕНИЕ
3 ответа
Я думаю, такое поведение может исходить из математики x87/sse2. Какую версию GCC вы используете? Вы используете float (32-битный) или двойной (64-битный)? Математика на x87 имеет больше внутренних битов точности (82), чем может храниться в памяти
Попробуйте флаги для gcc -ffloat-store; -msse2 -mfpmath=sse
Флаги для MSVC /fp:fast /arch:SSE2
1, вероятно, другая оптимизация некоторой библиотеки с плавающей точкой
2, это проблема?
редактировать:
Посмотрите на параметр "/fprecise" на VS ( http://msdn.microsoft.com/en-us/library/e7s85ffb.aspx) или "-fprecise-math" на gcc.
Что касается б), целочисленное и деление числа с плавающей запятой полностью определены в C99. C99 определяет округление к нулю для целых чисел (более ранние стандарты оставили определение направления округления определенным реализацией) и IEEE 754 для плавающей запятой.
Услышав, что VS2008 не претендует на реализацию C99, это не очень помогает. Определяемый реализацией, по крайней мере, означает, что вы можете написать несколько тестовых примеров и убедиться, какое решение было принято вашим компилятором.
Если вы действительно заботитесь об этом, как насчет инструментария кода для вывода подробных трасс в отдельный файл и проверки трасс на первое различие? Эй, возможно, трассировка уже есть для отладки!