2012-11-14 88 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.60000002 0.666666669 0.33333334]。任何人都可以提出一些想法來優化代碼?

+1

爲什麼你打算計算'int i = blockIdx.y * blockDim.y + threadIdx.y;'如果你馬上要丟棄它? –

+0

@PaulR:我是PyCuda的新手。啓動這樣的'我'是否有錯? –

+1

爲什麼要問如何優化什麼是有效的計算少量FLOP的完全串行代碼?另外,你爲什麼要進行整數初始求和呢?這是故意的嗎? – talonmies

回答

1

如果您的實際應用剛剛總結的一對值從a,存儲該總和c,然後正火對與和值並將其存儲在d,這樣的事情會是合理的:

__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對),則需要修改內核以處理多個輸入。如果出現這種可能性,我將把它作爲讀者的練習。