誰かが私が抱えている問題についての洞察を共有できることを願っています. 小さなプログラムは double の配列 (100000 要素) を取り、この配列のサブセットを加算して、結果を別の配列の要素に代入します。これは非常に基本的なタスクのように思えますが、私の GT630 は奇妙な動作をします。intervalLength の値が小さい場合は動作しますが (かなり遅くなります)、intervalLength が 300 前後に大きくなるとすぐに、コードは失敗します。
さらに興味深いのは、問題は加算ではなく、結果を出力配列に代入することにあるようです。以下のコードの最後の行の場合
output_dev[threadIdx.x] = totalSum;
に変更されます
output_dev[threadIdx.x] = input_dev[0];
その後、コードは非常に高速に実行されます。少なくとも 100 倍速くなり、intervalLength の値が大きくても機能します。また、行の場合
totalSum=1;
代入に先行すると、コードも高速でエラーなしで実行されます。いくつかの実験では、ループを使用するのではなく、一連のステートメントで合計を計算すると、コードも正常に機能することが示されました。
GT630 4GB を 96 個の CUDA スレッドで使用しており、1 つのブロックで 96 個のスレッドを起動しています。
コード:
extern "C" __global__ void TestCompute(double* input_dev, int input_devLen0, int* args_dev, int args_devLen0, double* output_dev, int output_devLen0)
{
int intervalLength = args_dev[0];
double totalSum = input_dev[num];
if (num < input_devLen0)
{
for (int k = 0; k <= input_devLen0; k++)
{
totalSum = 0.0;
for (int i = 0; i < intervalLength; i++)
{
if (input_devLen0 > i)
{
totalSum += input_dev[i];
}
}
if (output_devLen0 > threadIdx.x)
{
// totalSum = 1;
output_dev[threadIdx.x] = totalSum; // input_dev[0];
}
}
}
}