1

私はJavaで次のコードを持っています:

float in[][] = new float[2][2];

float B[] = new float[2]; 
float A[] = new float[2]; 
float res[] = new float[A[0].length];

for(float r : res){
    r = 0;
}

for (int i = 0; i < A[0].length; i++) {
    for (int j = 0; j < B[0].length; j++) {
        res[i] += A[j] * in[j][i];
}

せいぜい単純化しただけなので、実際のロジックを検索しないでください:)。

ループ内の += ステートメントのため、CUDA でこれを変換するのに数時間苦労しました。

私はこのようなものから始めました:

extern "C"
__global__ void filter(float* in, float* A, float* B, float* res, int in_size){

    unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
    unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;

    res[x] = A[y] * in[x + y * in_width];

}

しかし、すべてのスレッドが同じ変数を設定しようとしているために機能しないことにすぐに気付きました。

このプレゼンテーションで内積の例を読みましたが、in の 2 次元の必要性にそれを適応させる方法がよくわかりません。

私は完全な解決策を求めているわけではありませんが、どんな方向性も間違いなく歓迎されます.

どうも、

4

2 に答える 2

1

CUDA が多すぎて頭が死んでしまいました。

カーネル内のループの 1 つを展開することで、部分的な解決策を見つけました。現在の外観は次のとおりです。

extern "C"
__global__ void filter(float* in, float* A, float* res, const int in_width, const int sizeB){
    unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
    int i = 0;

    for(i = 0; i < sizeB; i++){
        res[x] += A[i] * in[i + x * in_width];
    }

}

私はもっ​​と良いものを見つけることができると確信していますが、今日はこれに固執すると思います:)

于 2012-09-25T14:07:47.593 に答える
0

乗算ジョブ A[j] * in[j][i] in A[0].length*B[0].length スレッドを分割し、乗算の結果を NVIDIA SDK の削減サンプルのように合計できます。共有メモリ

于 2012-09-25T17:04:20.687 に答える