문제

소프트웨어 프로젝트가있어 때때로 작고 간단한 부동 소수점 작업에서 이상한 결과를 얻습니다. 내가 놓친 것이 있다고 가정하고 다음 문제를 디버깅하는 방법에 대한 몇 가지 팁을 원합니다.

(사용 된 컴파일러는 MS VC 6.0, 즉 Microsoft C 컴파일러의 버전 12입니다)

첫 번째 이상 :

extern double Time, TimeStamp, TimeStep;  // History terms, updated elsewhere
void timer_evaluation_function( ) {
    if ( ( Time - TimeStamp ) >= TimeStep ) {  
        TimeStamp += TimeStep;  
        timer_controlled_code( );  
    }
{....}

어떤 이유로, 타이머 평가에 실패했고 시간이 정한 코드는 실행되지 않았습니다. 디버거에서, 트리그 조건이 실제로 사실이라는 것을 알기에는 아무런 문제가 없었지만 FPU는 긍정적 인 결과를 찾기를 거부했다. 다음 코드 세그먼트에는 동일한 작업을 수행했지만 문제가 없었습니다. 실패 할 수있는 가짜 평가를 삽입하여 문제가 발생했습니다.

FPU 상태가 어떻게 든 초기 작업에 의해 오염 된 것으로 추측하고 있으며, 도움이 될 컴파일러 플래그가 있다고 생각합니다.

두 번째 이상 :

double K, Kp = 1.0, Ti = 0.02;
void timed_code( ){
    K = ( Kp * ( float ) 2000 ) / ( ( float ) 2000 - 2.0F * Ti * 1e6 )
{....}

디버거가 방정식을 약 0.05로 평가하더라도 결과는 #ind입니다. 2.0F 값이 FPU에 FLD 명령을 사용하여로드되면 #ind 값이 FPU 스택에 나타납니다. 이전 명령은 정수 값 2000을 FILD 명령을 사용하여 이중 플로트로로드합니다. FPU 스택에 #ind 값이 모두 포함되면 ALL은 모두 손실되지만 디버거는 공식을 평가하는 데 아무런 문제가 없습니다. 나중에 이러한 작업은 예상 결과를 반환합니다.

또한 다시 한번 FPU 문제는 함수 호출 직후에 발생합니다. 각각의 새로운 기능 후에 FPU 상태를 지우는 부동 소수점 작업을 삽입해야합니까? 어떤 식 으로든 FPU에 영향을 줄 수있는 컴파일러 플래그가 있습니까?

이 시점에서 모든 팁과 요령에 감사드립니다.

편집 : 나는 최상위 기능에서 Assembly Function EMMS를 가장 먼저 호출하여 문제를 피할 수있었습니다. 이렇게하면 FPU에 내 코드가 호출되는 환경에서 만들어 졌을 수도 있고 없을 수도있는 MMX 관련 쓰레기가 지워집니다. FPU의 상태는 당연한 것으로 여겨지는 것 같습니다.

//솔직한

도움이 되었습니까?

해결책

Windows를 사용하는 경우 MMX를 지원하는 시스템에서 Windows QueryPerformanCecounter 및 QueryPerformanceFrequency 기능을 사용하는 경우 주파수/카운터를 쿼리 한 후 및 계산 전에 FEMMS 명령어를 삽입하십시오.

__asm femms

MMX를 사용하여 64 비트 계산을 수행하고 부동 소수점 플래그/상태를 지우지 않기 전에 이러한 기능에서 문제가 발생했습니다.

부동 소수점 작업 사이에 64 비트 산술이있는 경우 이러한 상황이 발생할 수 있습니다.

다른 팁

문제가 무엇인지 알지 못하지만 x86에서는 FPU를 해결합니다. 이론을 테스트하려면 코드 어딘가에 삽입 할 수 있습니다.

__asm {
    finit
}

그것은 실제로 당신의 질문에 대한 답이 아니지만, 당신은 이상한 FPU 행동에 관한 Raymond Chen의 두 기사를보고 싶을 수도 있습니다. 귀하의 질문을 읽고 기사를 다시 읽은 후에는 즉시 링크를 보지 못합니다. 그러나 당신이 붙인 코드가 완료되지 않았거나 기사가 당신에게 문제를 일으킨 주변 행동에 대한 아이디어를 주면 .. 특히 DLL을 근처에로드하는 경우.

비 초기 부동물 지점 변수는 치명적일 수 있습니다

비활성화 할 때 유효하지 않은 부동 소수점 피연산자 예외는 어떻게 발생 했습니까?

나는 당신에게 정확한 솔루션을 제공하지는 않지만, 나는 당신이 이것을 읽는 것으로 시작하는 것이 좋습니다. 기사 이는 사용할 수있는 다양한 최적화를 설명합니다.

Re : 타임 스탬프-

타임 스탬프 소스를 얻는 것은 무엇입니까? 뭔가 의심 스러워요. 파일에 로그인하십시오.

불량 값이 2.0을로드 해야하는 FLD에 의해로드되면이 값이로드 된 메모리를 확인합니다. 단지 컴파일러/링커 문제 일 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top