2016-06-19 4 views
0

everyone.get_global_size (0) 컨트롤러가 작동하지 않습니다.

__kernel void FuncionCL(__global char* in, __global char* out, __global int* S2) 
{ 
    __private int op1, op2, op3; 
    __private int C; 
    __private uint WorkDim, C2; 
    op1 = 1; 
    op2 = 2; 
    WorkDim = get_global_size(0); 
    __private int ID; 
    ID = get_global_id(0); 
    for(C = 0; C < 1000000; C++) 
    { 
     for(C2 = ID; C2 < 1000; C2 += WorkDim) 
     { 
      op3 = op1 + op2; 
     } 
    } 
    out[0] = 90; 
    out[1] = 89; 
    *S2 = (int) WorkDim; 
} 

그것은 응용 프로그램, 너무 그래픽 컨트롤러뿐만 아니라 충돌 :

나는이 커널을 얻었다. 나는 상수 값 '16'(get_global_size() 함수가 반환)에 대한 증분을 변경하면 코드가 제대로 실행됩니다. 뭐가 문제 야? 대신 8 번

WorkDim = 16; 

: 내가 가진 코드를 실행하면

WorkDim = get_global_size(0); 

코드는 문제의 400 배 빠르게 실행됩니다. 왜 값이 같으면?

** 편집 : **, 코드가 너무 느리고 곱하기 이유가 왜 자, 이제 내가 아는 :

1.- 투숙.

2 개 .- 모든 스레드가 첫 번째 루프에서 같은 반복을 오른쪽 코드는 다음과 같습니다

이 FuncionCL 무효 __kernel (__ 글로벌 숯불 *에서, __global 문자 * 밖으로, __global INT * S2) { __private int op1, op2, op3; __private int C; __private uint WorkDim, C2; op1 = 1; op2 = 2; WorkDim = get_global_size (0); __private int ID; ID = get_global_id (0); 위한 (C = ID, C < 1,000,000; C + = WorkDim) 용 { (ID = C2, C2 < 1,000; C2 + = WorkDim) { OP3 = OP1, OP2 +; } } out [0] = 90; out [1] = 89; * S2 = (int) WorkDim; }

내 코드는 CPU보다 GPU에서 6.1 배 빠릅니다.

+0

즉시 또는 일정 시간 후 (예 : 5 ~ 10 초) 충돌이 발생합니까? 후자의 경우, 커널이 너무 오래 걸리기 때문에 GPU를 재설정하는 것은 OS GPU 워치 독 타이머입니다. 이상적으로 커널이 50 밀리 초 미만으로 걸리게하거나 시스템 응답성에 영향을주기 시작하는 것이 이상적입니다 (UI 그리기 등에도 사용되기 때문에). – Dithermaster

+0

답변 해 주셔서 감사합니다. 예, 5 초 후에 충돌합니다. 그러나 질문은 그 이유가 무엇입니까?마치 WorkDim의 값 대신 상수 값인 incrment를 사용하면 커널은 '16'(get_global_size (0)의 값을 반환)을 반환하지만 get_global_size (0)은 0을 반환하고 루프는 끝나지 않습니다. –

답변

0

각 항목마다 1000000 * 1000 = 1Gop을 수행하고 있습니다. 너무 많은 시간이 걸리므로 드라이버가 GPU를 다시 시작합니다. (예를 들어 전체 크기가 1이라고 가정합니다.)

작업 항목이 적은 CL 커널을 실행하는 데 리소스가 낭비되기 때문에 GPU가 거의 직렬 계산을 수행하고 너무 오래 걸릴 수 있습니다.

리소스를 최대한 활용하려면 새 GPU에 적어도 1024 개의 글로벌 항목이 필요합니다.

편집 : 루프는 아마도 정적 값을 가질 때 컴파일러에 의해 최적화됩니다. 따라서 "놀라운"속도 향상을 제공합니다.

+0

좋아요, 1Gflop은 너무 많은데, "WorkDim = 16;"코드를 실행하면 "WorkDim = get_global_size (0)"보다 너무 빨리 실행됩니다. 내가 100 * 1000 반복과 두 코드 사이의 시간 차이의 코드를 실행했습니다 "get_global_size (0)"로 반환 된 값으로 약 400 배 느립니다. 자, 왜 내가 16 개의 작업 항목으로이 코드를 실행하는지 reazon은 GeForce210 (16 CUDA 코어)을 가지고 있기 때문입니다. –

+0

그런 식으로 디자인해야합니다. 필요에 따라 많은 항목을 실행하고 가능한 한 병렬로 장치를 보냅니다. 단 16 개의 항목을 사용하는 것이 모든 장치를 사용하지는 않습니다 (각 CUDA 코어는 최신 장치에서 64 개 이상의 항목까지 실행할 수 있습니다). – DarkZeros

+0

하드 코딩하여 성능을 향상시킨 이유는 컴파일러 최적화를 쉽게 추측 할 수 있기 때문입니다. 루프의 유용한 데이터를 저장하지 않고 루프 매개 변수가 가변적 인 경우 최적화 할 수 없지만 정적 인 경우 컴파일러는 단순히 전체 루프를 제거합니다. – DarkZeros

관련 문제