2012-02-14 4 views
0

왜 CUDA를 사용하면 1 백만 크기의 FFT를 수행 할 때마다 매번 약간 다른 결과가 나옵니까?동일한 데이터를 CUDA로 FFT하면 매번 다른 결과가 나타 납니까?

내 하드웨어에는 페르미 아키텍처가 있습니다.

+0

이것은 흥미 롭습니다. 당신이하고있는 일을 보여주는 몇 가지 코드를 게시 할 수 있습니까? –

+2

매번 조금씩 미묘하게 다른 것을하고 있기 때문일 가능성이 큽니다. 이 문제를 보여주는 최소한의 예를 보여주십시오. – Bart

+0

일부 코드를 게시하는 것 외에도 "미묘하게 다른"설명이 필요합니다. –

답변

4

쉽게 대답 할 수 있습니다. CUDA 프로그램은 double보다 상당히 빠르기 때문에 float 변수 유형을 자주 사용합니다. 연산이 평가되는 순서는 부동 소수점 계산의 최종 값에 큰 영향을 줄 수 있습니다. 이것은 CUDA만의 독특한 것은 아니지만, 대단히 평행 한 패러다임이기 때문에 특히 효과가 뚜렷하게 나타날 수 있습니다 (그리고 병렬 처리는 최소한 글로벌 축소와 같은 일을 할 때 비 결정적입니다).

EDIT : CUDA가 동일한 커널이 여러 차례 실행될 때 동일한 순서로 실행된다는 것을 보장하지 않는다는 것이 확실합니다. CUDA가이를 보장한다면, 산술 연산이 실행되는 순서가 달라져서는 안되며, 따라서 동일한 부동 소수점 연산에 대해 다른 값을 기대하지 않을 것입니다.

위의 주장을 보여주는 간단한 C 프로그램이 있습니다. 리눅스의 코드

#include <stdio.h> 

int main() 
{ 
    float a = 100.0f, b = 0.00001f, c = 0.00001f; 

    printf("a + b + c = %f\n", a + b + c); 
    printf("b + c + a = %f\n", b + c + a); 
    printf("a + b + c == b + c + a ? %d\n", (a + b + c) == (b + c + a)); 

    return 0; 
} 

을 시도하고 (I 64 비트 RHEL 6 GCC 버전 4.4.4-13을 사용하고) 당신이 무엇을 얻을 참조하십시오.

[[email protected] directory]# gcc add.c -o add 
[[email protected] directory]# ./add 
a + b + c = 100.000015 
b + c + a = 100.000023 
a + b + c == b + c + a ? 0 

편집이 :이 프로그램은 근본적인 문제가 부동 소수점 또한 비 교환 법칙이 성립 있다는 것을 제안 할 수 있습니다 동안 있습니다, 실제로 부동 소수점 또한이 비 인 경우입니다 내 출력은 다음과 같다 associative (C는 왼쪽에서 오른쪽으로의 덧셈 연산을 평가하기 때문에 첫 번째 덧셈은 (a + b) + c로 수행되고 두 번째 덧셈은 (b + c) + a)로 수행됩니다. 비 연관성 (non-associativity)의 이유는 부동 소수점 표현이 유한 한 많은 유효 자릿수 (기수 2에서는 표현할 수 있지만 기수 10 시스템에 대한 논의는 본질적으로 동등 함)를 나타낼 수 있기 때문입니다. 예를 들어, 유효 숫자 3 자리 만 표현할 수있는 경우, (100 + 0.5) + 0.5 = 100 + 0.5 = 100, 100 + (0.5 + 0.5) = 100 + 1 = 101이됩니다. 첫 번째 경우, 3 개의 유효 숫자만으로 중간 값 100.5를 나타낼 수 없기 때문에 결과 100 + 0.5는 잘 리거나 (또는 ​​반올림해야 함) 절단해야합니다.

이 현상에는 여러 가지 중요한 의미가 있습니다. 예를 들어 크기 (지수)가 증가하는 순서로 숫자를 추가하여보다 정확한 답을 얻을 수 있습니다. 실제 계산은 계산이 동일한 순서로 수행되지 않는 한 결과가 동일하다고 기대하면 안되기 때문에 실제 GPU에서 CUDA를 사용하는 것을 보장하기 어려울 수 있습니다.

+1

이것은 동일한 입력 데이터에서 실행 간 차이를 어떻게 설명 할 것인가? 하드웨어가 무작위로 실행을 순서대로 재주문해야 하는가? 내 경험상, 실행 순서는 선험적으로 결정할 수 없지만 하드웨어는 동일한 코드의 실행 순서를 무작위로 지정하지 않습니다. – talonmies

+1

@talonmies CUDA가 동일한 실행 명령을 연속적으로 실행할 것을 보장한다는 것이 내 인상이 아니 었습니다. 실행이 무작위로 실행되지는 않지만 (어떤 의도로) 실행이 무작위로 실행되는 것은 아니지만 일종의 간섭 등이있을 수 있습니다.CUDA가 그러한 보증을 제공한다면, 나는이 답변이 틀리다고 동의하고이를 제거 할 것입니다. – Patrick87

+2

첫 번째 발급 된 블록이 매번 다른 다중 프로세서로 발행 될 수 있으며, 다중 프로세서 전반에 고르지 않은 블록 수가있는 경우 실행 순서가 실행간에 약간 다를 수 있습니다. 원자가 관련되어 있고 메모리 주소가 실행에 따라 다르면 실행 순서가 더 변경 될 수 있습니다. BTW @ Patrick87, 실수로 부동 소수점 실행 차이에 대한 설명을하기 위해,이 모든 실제 이유는 "부동 소수점 산술은 비 연관"이라는 것을 지적하고 싶을 수 있습니다. – harrism

관련 문제