0

グローバル関数からデバイス関数を呼び出そうとしています。この関数は、すべてのスレッドで使用される配列を宣言しているだけです。しかし、配列を印刷したときの問題は、その要素が宣言された順序と同じではありません。すべてのスレッドが再び配列を作成しているためですか? スレッドについて混乱しました。もしそうなら、どのスレッドがグローバル関数で最初に実行されるかを知ることができますか、そしてそれが他のスレッドの配列を宣言することだけを許可することはできますか? ありがとう。ここで配列を作成する私の関数:

__device__ float myArray[20][20];

__device__ void calculation(int no){
filterWidth = 3+(2*no);
filterHeight = 3+(2*no);
int arraySize = filterWidth;
int middle = (arraySize - 1) / 2;
int startIndex = middle;
int stopIndex = middle;

// at first , all values of array are 0
for(int i=0; i<arraySize; i++)
    for (int j = 0; j < arraySize; j++)
    {
        myArray[i][j] = 0;
    }

//  until middle line of the array, required indexes are 1
for (int i = 0; i < middle; i++)
{
    for (int j = startIndex; j <= stopIndex; j++)
    { myArray[i][j] = 1; sum+=1; }
    startIndex -= 1;
    stopIndex += 1;
}

// for middle line
for (int i = 0; i < arraySize; i++)
{myArray[middle][i] = 1; sum+=1;}

// after middle line of the array, required indexes are 1
startIndex += 1;
stopIndex -= 1;
for (int i = (middle + 1); i < arraySize; i++)
{
    for (int j = startIndex; j <= stopIndex; j++)
    { myArray[i][j] = 1; sum+=1; }
    startIndex +=1 ;
    stopIndex -= 1;
}


filterFactor = 1.0f / sum;
  } 

そしてグローバル関数:

__global__ void FilterKernel(Format24bppRgb* imageData)
  {
int tidX = threadIdx.x + blockIdx.x * blockDim.x;
int tidY = threadIdx.y + blockIdx.y * blockDim.y;

Colour Cpixel = Colour (imageData[tidX + tidY*imageWidth] );
float depthPixel =  Colour(depthData[tidX + tidY*imageWidth]).Red;
float absoluteDistanceFromFocus = fabs (depthPixel - focusDepth);


if(depthPixel == 0)
    return;

Colour Cresult = Cpixel;
for (int i=0;i<8;i++)
{
    calculation(i);
     ...
     ...
    }
 }
4

1 に答える 1

0

本当に選択して 1 つのスレッドに関数を呼び出しさせ、残りのスレッドをそれが呼び出されるまで待機させたい場合は__shared__、デバイス関数によって作成された配列にメモリを使用して、ブロック内のすべてのスレッドが同じものを参照できるようにします。次のように呼び出します。

for (int i=0;i<8;i++)
{
    if (threadIdx.x == 0 && threadIdx.y == 0)
        calculation(i);
    __syncthreads();
    ...
}

もちろん、これはブロック間では機能しません。グローバルに定義された関数では、ブロックが計算される順序を制御できません。

代わりに、可能であれば、カーネルを起動する前に、CPU で初期化計算 (1 つのスレッドのみで実行する必要がある計算) を実行し、それを GPU に memcpy する必要があります。myArray に 8 倍のメモリを使用するように見えますが、計算が劇的に高速化されます。

于 2012-04-25T19:29:01.697 に答える