2012-11-14 3 views
1

다음과 같이 배열을 정규화하려고합니다.배열의 정규화에 관한 Cuda 커널 최적화

  1. 배열의 처음 두 요소를 선택하고 합계를 찾아 그 합계를 사용하여 나눕니다.
  2. 나머지 요소에 대해서도 동일한 작업을 수행하십시오.

잘 작동합니다. 그러나 배열의 차원을 늘리면 시간 복잡성이 생깁니다. 아래 코드를 입력했습니다.

import pycuda.driver as drv 
import pycuda.autoinit 
from pycuda.compiler import SourceModule 
import numpy as np 

mod=SourceModule(""" 
__global__ void addition(float* a,float* c,float* d) 
{ 
int i=blockIdx.y*blockDim.y+threadIdx.y; 
for (i=0;i<=4;++i) 
{ 
    int sum=0.0; 
    for (int j=0;j<=1;++j) 
    { 
     sum+=a[2*i+j]; 
    } 
c[i]=sum; 
} 
for (i=0;i<=4;i++) 
{ 
    for (int j=0;j<=1;++j) 
    { 
     d[2*i+j]=a[2*i+j]/c[i]; 
    } 
} 
} 
""") 

addition=mod.get_function("addition") 
a=np.array([1,2,3,1,2,3,2,1]).astype(np.float32) 
c=np.zeros_like(a) 
d=np.zeros_like(a) 
addition(drv.In(a),drv.InOut(c),drv.InOut(d),block=(1,8,1)) 
print d 

(D)의 결과는 [0.33333334 0.66666669 0.75 0.25 0.40000001 0.666666669 0.60000002 0.33333334]. 누구든지 코드를 최적화 할 수있는 아이디어를 제안 할 수 있습니까?

실제 응용 프로그램이 단지 c에 그 합을 저장 한 후 합계와 값의 쌍을 정상화하고 d에 저장, a에서 값의 쌍을 합산 한 경우
+1

왜 즉시'int i = blockIdx.y * blockDim.y + threadIdx.y; '를 계산해야합니까? –

+0

@PaulR : 나는 PyCuda를 처음 사용합니다. 'i'를 시작하는 것이 잘못된 것인가? –

+1

그리고 왜 소수의 FLOP을 계산할 수있는 완전한 직렬 코드가 최적화되어 있는지 묻는 것이 어떻습니까? 또한 정수에서 초기 합계를 수행하는 이유는 무엇입니까? 그게 신중한가요? – talonmies

답변

1

,이 같은 합리적인 것 :

__global__ void addition(float* a, float* c, float* d) 
{ 
    int idx = threadIdx.x + blockDim.x*blockIdx.x; 

    float2* avec = reinterpret_cast<float2*>(a); 
    float2* dvec = reinterpret_cast<float2*>(d); 

    float2 val = avec[idx]; 
    float sum = val.x + val.y; 
    val.x \= sum; 
    val.y \= sum; 

    c[idx] = sum; 
    dvec[idx] = val;  
} 

[면책 조항 : 브라우저에 기록이 컴파일 결코 자신의 위험에 사용, 화재에 GPU를 설정하지 보장 할 수 없습니다, 테스트하지 각 스레드 처리와,

다음

벡터 형 메모리 처리량을 개선하는 데 사용됩니다 한 쌍의 값. N 값의 경우, N/2 스레드를 실행하십시오. 131070 개 이상의 입력 값 (65535 쌍)이있는 경우 둘 이상의 입력을 처리하도록 커널을 수정해야합니다. 나는 그러한 결과가 발생할 경우 독자를위한 운동으로 남겨 둘 것입니다.