しばらく前に、同様のことを行う次のコードを書きました。
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <stdlib.h>
__global__ void fast_finder(unsigned int *g_found, float x, float *y)
{
unsigned int i = blockIdx.x * blockDim.x + threadIdx.x;
unsigned int pos = (unsigned int)(x == y[i]);
g_found[i * (1 - pos)] = i * pos;
}
int main(int argc, char *argv[])
{
int N = 65536;
unsigned int h_found, *d_found;
float *h_y = (float *)malloc(N * sizeof(float)), *d_y, x = 5.0f;
int nThreads = 1024, nBloks = N / nThreads;
for (int i = 0; i < N; ++i) h_y[i] = (float)(N - i - 1);
if (x != h_y[0]) {
cudaSetDevice(0);
cudaMalloc((void **)&d_found, N * sizeof(unsigned int));
cudaMalloc((void **)&d_y, N * sizeof(float));
cudaMemcpy(d_y, h_y, N * sizeof(float), cudaMemcpyHostToDevice);
fast_finder<<<nBloks, nThreads>>>(d_found, x, d_y);
cudaThreadSynchronize();
cudaMemcpy(&h_found, d_found, sizeof(unsigned int), cudaMemcpyDeviceToHost);
if (h_found) printf("%g found on %d. position!\n", x, h_found);
else printf("%g not found!\n", x);
cudaFree(d_y);
cudaFree(d_found);
} else printf("%g found on the first position!\n", x);
free(h_y);
getchar();
return EXIT_SUCCESS;
}
ここで、各スレッドは、グローバル スレッド インデックスによって提供される値y
が と等しいかどうかをチェックしx
ます。true の場合、スレッドはそのインデックスをg_found
配列の最初の位置に書き込みます。それ以外の場合はg_found
、インデックスによって提供される位置に 0 を書き込みます。y
長さ 16 の場合、出力の 11 番目の位置に値 5 を含むとy
、次のようになります。
g_found = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
この場合y
、並べ替える必要はありませんが、一意の値のみを含める必要があります。x
このコードは、次のように、提供されたものが挿入される 1 つの検出結果 (デバイス部分) インデックスに簡単に変更できます。
__global__ void fast_finder(unsigned int *g_found, float x, float *y)
{
unsigned int i = blockIdx.x * blockDim.x + threadIdx.x;
unsigned int pos = (unsigned int)(x >= y[i] || x <= y[i+1]);
g_found[i * (1 - pos)] = (i + 1) * pos;
}
このバージョンの出力は、私のものと似ています。g_found
位置 0 が 0 の場合、 の値は配列x
に存在しませんy
。isの最初の要素y
が等しいかどうかはx
、カーネルが呼び出される前に、ホスト コードによってチェックされます。この部分も変更して条件を適用しても問題ありません。
ご覧のとおり、このようなソリューションでは、すべてのスレッドが連携して動作し、実行を終了する必要はありませんx
。良いことは、パケット検索を適用することです。つまり、1 つのスレッドを の小さなサブセットでシークするように割り当てることで、はるかに大きくすることがy
できます。y