부동 소수점 마이그레이션 문제Floating-point migration issues

프로젝트를 최신 버전의 Visual Studio로 업그레이드할 때 특정 부동 소수점 연산의 결과가 변경될 수 있습니다.Sometimes when you upgrade your projects to a newer version of Visual Studio, you may find that the results of certain floating-point operations have changed. 일반적으로 이 문제는 두 가지 이유 즉, 사용 가능한 프로세서를 더 효율적으로 활용하는 코드 생성 변경, CRT(C 런타임 라이브러리)에서 수학 함수에 사용된 알고리즘 변경 또는 버그 수정 중 한 가지 이유로 인해 발생합니다.This generally happens for one of two reasons: Code generation changes that take better advantage of the available processor, and bug fixes or changes to the algorithms used in math functions in the C runtime library (CRT). 일반적으로 언어 표준에 지정된 범위 내에서는 새 결과가 올바릅니다.In general, the new results are correct to within the limits specified by the language standard. 변경된 내용과 함수에서 이전에 얻은 것과 동일한 결과를 구하는 방법을 알아보려면 계속 읽어보세요.Read on to find out what's changed, and if it's important, how to get the same results your functions got before.

새 수학 함수 및 유니버설 CRT 변경New math functions and Universal CRT changes

대부분의 CRT 수학 함수가 수 년 동안 Visual Studio에서 사용 가능했지만, Visual Studio 2013 이상에는 ISO C99에 필요한 모든 함수가 포함되어 있습니다.Most CRT math functions have been available in Visual Studio for years, but starting in Visual Studio 2013, all of the functions required by ISO C99 are included. 이러한 함수는 수정을 통해 성능을 균형있게 분배하도록 구현됩니다.These functions are implemented to balance performance with correctness. 모든 경우에 올바르게 반올림된 결과를 생성하는 것은 막대한 비용이 들 수 있으므로 이러한 함수는 올바르게 반올림된 결과에 대한 근사치를 효율적으로 생성하도록 설계됩니다.Because producing the correctly rounded result in every case may be prohibitively expensive, these functions are designed to efficiently produce a close approximation to the correctly rounded result. 부정확성이 더 큰 경우도 있을 수 있지만 대부분은 생성된 결과가 올바르게 반올림된 결과의 +/-1 ULP(Unit of Least Precision) 내에 있습니다.In most cases, the result produced is within +/-1 unit of least precision, or ulp, of the correctly rounded result, though there may be cases where there is greater inaccuracy. 이전에는 다른 수학 라이브러리를 사용하여 이러한 함수를 가져올 경우 구현 차이로 인해 결과가 변경될 수 있었습니다.If you were using a different math library to get these functions before, implementation differences may be responsible for the change in your results.

Visual Studio 2015에서 수학 함수를 유니버설 CRT로 이동하면서 몇 가지 새로운 알고리즘을 사용하고 Visual Studio 2013에서 새롭게 발생한 여러 함수 구현 관련 버그를 수정했습니다.When the math functions were moved to the Universal CRT in Visual Studio 2015, some new algorithms were used, and several bugs in the implementation of the functions that were new in Visual Studio 2013 were fixed. 이러한 변경으로 인해 해당 함수를 사용하는 부동 소수점 계산 결과가 달라질 수 있습니다.These changes can lead to detectable differences in the results of floating-point calculations that use these functions. 버그 문제가 있었던 함수로는 erf, exp2, remainder, remquo, scalbln, scalbn 등과 이들의 float 및 long double variant가 있습니다.The functions that had bug issues were erf, exp2, remainder, remquo, scalbln, and scalbn, and their float and long double variants. 또한 Visual Studio 2015에서는 _clear87, _clearfp, fegetenv, fesetenv 및 feholdexcept 함수의 부동 소수점 상태 단어 및 예외 상태 정보 유지 관련 문제가 해결되었습니다.Other changes in Visual Studio 2015 fixed issues in preserving floating point status word and exception state information in _clear87, _clearfp, fegetenv, fesetenv, and feholdexcept functions.

프로세서 차이점 및 컴파일러 플래그Processor differences and compiler flags

대부분의 부동 소수점 수학 라이브러리 함수에는 다양한 CPU 아키텍처에 대한 다양한 구현이 있습니다.Many of the floating point math library functions have different implementations for different CPU architectures. 예를 들어 32비트 x86 CRT에는 64비트 x64 CRT와 다른 구현이 있을 수 있습니다.For example, the 32-bit x86 CRT may have a different implementation than the 64-bit x64 CRT. 또한 일부 함수에는 지정된 CPU 아키텍처에 대한 여러 구현이 있을 수 있습니다.In addition, some of the functions may have multiple implementations for a given CPU architecture. 가장 효율적인 구현은 CPU에서 지원되는 명령 집합에 따라 런타임에 동적으로 선택됩니다.The most efficient implementation is selected dynamically at run-time depending on the instruction sets supported by the CPU. 예를 들어 32비트 x86 CRT에서 일부 함수에는 x87 구현 및 an SSE2 구현이 둘 다 있습니다.For example, in the 32-bit x86 CRT, some functions have both an x87 implementation and an SSE2 implementation. SSE2를 지원하는 CPU에서 실행될 경우 더 빠른 SSE2 구현이 사용됩니다.When running on a CPU that supports SSE2, the faster SSE2 implementation is used. SSE2를 지원하지 않는 CPU에서 실행될 경우 더 느린 x87 구현이 사용됩니다.When running on a CPU that does not support SSE2, the slower x87 implementation is used. 기본 x86 컴파일러 아키텍처 옵션이 Visual Studio 2012에서 /arch:SSE2로 변경되었기 때문에 이전 코드를 마이그레이션할 때 이렇게 표시될 수 있습니다.You may see this when migrating old code, because the default x86 compiler architecture option changed to /arch:SSE2 in Visual Studio 2012. 수학 라이브러리 함수의 구현에 따라 다른 CPU 명령 및 다른 알고리즘을 사용하여 결과를 생성할 수 있으므로 플랫폼에 따라 함수에서 다른 결과가 생성될 수 있습니다.Because different implementations of the math library functions may use different CPU instructions and different algorithms to produce their results, the functions may produce different results on different platforms. 대부분은 결과가 올바르게 반올림된 결과의 +/-1 ulp 내에 있지만 실제 결과는 CPU에 따라 달라질 수 있습니다.In most cases, the results are within +/-1 ulp of the correctly rounded result, but the actual results may vary across CPUs.

또한 Visual Studio에서 다른 부동 소수점 모드의 코드 생성 정확성이 향상되어 부동 소수점 연산 결과에 영향을 줄 수 있습니다. 이는 이전 코드와 새 코드에서 동일한 컴파일러 플래그를 사용하더라도 마찬가지입니다.Code-generation correctness improvements in different floating point modes in Visual Studio can also affect the results of floating-point operations when old code is compared to new code, even when using the same compiler flags. 예를 들어 /fp:precise(기본값) 또는 /fp:strict를 지정할 때 Visual Studio 2010에서 생성되는 코드는 식을 통해 중간 NaN(Not-a-Number) 값을 올바르게 전파하지 못할 수 있습니다.For example, the code generated by Visual Studio 2010 when /fp:precise (the default) or /fp:strict was specified may not have propagated intermediate not-a-number (NaN) values through expressions correctly. 따라서 이전 컴파일러에서 숫자 결과를 제공하는 일부 식에서 이제 올바른 NaN 결과를 생성할 수 있습니다.Thus, some expressions that gave a numeric result in older compilers may now correctly produce a NaN result. /fp:fast에 대해 활성화된 코드 최적화에서 이제 더 많은 프로세서 기능을 이용하기 때문에 차이가 나타날 수도 있습니다.You may also see differences because the code optimizations enabled for /fp:fast now take advantage of more processor features. 이러한 최적화로 더 적은 명령을 사용할 수 있지만 이전에 표시된 일부 중간 연산이 제거되었기 때문에 생성되는 결과에 영향을 줄 수 있습니다.These optimizations can use fewer instructions, but may impact the generated results because some previously visible intermediate operations have been removed.

동일한 결과를 얻는 방법How to get identical results

대부분의 경우 최신 컴파일러 및 라이브러리의 부동 소수점 변경으로 인해 더 빠르거나 더 정확하게 동작합니다.In most cases, the floating-point changes in the newest compilers and libraries result in faster or more correct behavior, or both. x87 명령을 SSE2 명령으로 바꾸면 프로세서 전원 성능이 향상될 수 있습니다.You may even see better processor power performance when SSE2 instructions replace x87 instructions. 하지만 이전 컴파일러의 부동 소수점 동작을 정확하게 복제해야 하는 코드가 있는 경우 Visual Studio 네이티브 멀티 타기팅 기능을 사용하고 이전 도구 집합으로 해당 프로젝트를 빌드하는 것이 좋습니다.However, if you have code that must precisely replicate the floating point behavior of an older compiler, consider using Visual Studio native multi-targeting capabilities, and build the affected project with the older toolset. 자세한 내용은 Visual Studio의 네이티브 멀티 타기팅을 사용하여 이전 프로젝트 빌드를 참조하세요.For more information, see Use native multi-targeting in Visual Studio to build old projects.

참고 항목See also

이전 버전의 Visual C++에서 프로젝트 업그레이드Upgrading Projects from Earlier Versions of Visual C++
잠재적인 업그레이드 문제 개요(Visual C++)Overview of potential upgrade issues (Visual C++)
Visual C++ 변경 기록 2003 - 2015Visual C++ change history 2003 - 2015