2010-01-12 9 views
4

첫 번째 데이터 세트의 추가 실행 시간은 어떻게됩니까? 조립 지침은 동일합니다.부동 소수점 연산 실행 시간

DN_FLUSH 플래그가 켜져 있지 않으면 첫 번째 데이터 세트는 63 밀리 초가 걸리고 두 번째 세트는 15 밀리 초가 걸립니다.
DN_FLUSH 플래그가 켜지면 첫 번째 데이터 세트는 15 밀리 초가 걸리고 두 번째 세트는 ~ 0 밀리 초가 걸립니다.

따라서 두 경우 모두 첫 번째 데이터 집합의 실행 시간이 훨씬 더 깁니다.

실행 시간을 줄여서 두 번째 데이터 세트에 가까워 질 수있는 방법이 있습니까?

저는 Intel Core 2 Duo T7700 @ 2.4Ghz Windows XP Pro에서 C++ Visual Studio 2005,/arch : SSE2/fp : 빠른 실행을 사용하고 있습니다. 인텔의 최적화 설명서에서 인용

#define NUMLOOPS 1000000 

// Denormal values flushed to zero by hardware on ALPHA and x86 
// processors with SSE2 support. Ignored on other x86 platforms 
// Setting this decreases execution time from 63 milliseconds to 16 millisecond 
// _controlfp(_DN_FLUSH, _MCW_DN); 

float denormal = 1.0e-38; 
float denormalTwo = 1.0e-39; 
float denormalThree = 1; 

tickStart = GetTickCount(); 

// Run First Calculation Loop 
for (loops=0; loops < NUMLOOPS; loops++) 
{ 
    denormalThree = denormal - denormalTwo; 
} 

// Get execution time 
duration = GetTickCount()-tickStart; 
printf("Duration = %dms\n", duration); 

float normal = 1.0e-10; 
float normalTwo = 1.0e-2; 
float normalThree = 1; 

tickStart = GetTickCount(); 

// Run Second Calculation Loop 
for (loops=0; loops < NUMLOOPS; loops++) 
{ 
    normalThree = normal - normalTwo; 
} 

// Get execution time 
duration = GetTickCount()-tickStart; 
printf("Duration = %dms\n", duration); 
+3

GetTickCount()는 타이밍 코드에 거의 가치가 없다는 것을 알아야합니다. 입상 성은 시스템마다 매우 다양하며 아마도 100ms 정도의 큰 경향이 있습니다. QueryPerformanceCounter()를 대신 사용하십시오. –

+0

QueryPerformanceCounter()는 사용할 고통입니다 ... timeGetTime()을 시도하십시오. 또한 GetTickCount()는 몇 초 이상 실행되는 것에 좋지 않습니다. 정확성을 알고 있어야합니다. – Inverse

+0

BTW,/arch를 사용한다고 가정하지 마십시오 : SSE2/fp : fast는 실제로 코드를 빠르게 만듭니다.내 코드의 경우, 나는/fp : precise를 발견했으며 FP 스택을 사용하는 것이 실제로 더 빠릅니다. 마찬가지로, 수레가 double보다 빠르다고 가정하지 마십시오. 모든 옵션을 테스트하십시오. – Joe

답변

11

는 :

SIMD 부동 소수점 명령에 대한 입력 오퍼랜드 [여기 포함 SSE를 사용하여 수행 스칼라 산술]하면 미만 값을 포함 데이터 형식의 표현 가능한 범위 인 비정규 예외가 발생합니다. 이 은 상당한 성능을 초래합니다 패널티. SIMD 부동 소수점 연산은 결과가 언더 플로우되지 않는 에 0으로 플러시 모드를가집니다. 따라서 후속 계산은 은 denormal 입력 피연산자를 처리하는 성능 패널티 인 에 직면하지 않습니다.

비정품을 제거 할 수없는 경우 : 데이터를 적절하게 조정하고 처음에 비정상 종료가 발생하지 않도록하려면 수행 할 수있는 작업을 수행하십시오. 보통 이것은 다른 모든 계산을 완료 할 때까지 일부 축척 비율을 적용하는 것을 지연시키는 것을 의미합니다.

또는 지수 범위가 훨씬 큰 double의 계산을 수행하면 처음에는 비정규 값이 발생할 가능성이 훨씬 줄어 듭니다.

+2

그건 그렇고, 'float'의 denormal 한도는 대략 1.18e-38이고'double '의 것은 대략 2.225e-308입니다. – kennytm

+3

@KennyTM :베이스 2를 사용하고 근사값을 피하십시오. '2 ** - 126'에서 float 언더 플로가 발생하고'2 ** - 1022'에서 두 배가됩니다. –

2

인텔 매뉴얼의 또 다른 인용, 볼륨 1 장 10.2.3.3는 : 754 IEEE는 언더하는 마스크 응답을 위임 모드는 IEEE 표준과 호환되지 않습니다 플러시 - 투 - 제로

은을 제공하는 것입니다 비정규 화 된 결과 ( 4.8.3.2 절, "정규화 및 비정규 화 된 유한 수"참조). 0 플러시모드는 주로 성능상의 이유에 대해 제공됩니다. 약간의 정밀도가 느껴지면 손실이 발생하므로 언더 플로가 공통 인 응용 프로그램에 대해서는 더 빠른 실행을 얻을 수 있으며 언더 플로 결과를 0으로 반올림하는 것이 허용 될 수 있습니다.