私の問題は次のとおりです。GPUを使用していくつかの興味のあるポイントを検出したイメージがあります。検出は処理の点では重量テストですが、平均でテストに合格するのは約25ポイントにすぎません。アルゴリズムの最終段階は、ポイントのリストを構築することです。 CPU上では、これは次のように実装されます:CUDAとの共有メモリミューテックス - アイテムリストへの追加
forall pixels x,y
{
if(test_this_pixel(x,y))
vector_of_coordinates.push_back(Vec2(x,y));
}
私は各CUDAブロックで16x16ピクセルを処理しています。問題は、最終的にグローバルメモリ内のポイントの単一の統合リストを持つためには特別なことをする必要があることです。現時点では、最終的にグローバルメモリに書き込まれるブロックごとの共有メモリ内のポイントのローカルリストを生成しようとしています。私はCPUに何かを返すことを避けようとしています。そのあとでCUDAのステージが増えています。
私は、共有メモリ上でpush_back関数を実装するためにアトミック操作を使用できることを期待していました。しかし、私はこれを得ることができません。 2つの問題があります。最初の厄介な問題は、次のようなコンパイラクラッシュに常に遭遇していることです。「nvccエラー: 'ptxas'がアトミック操作を使用すると状態0xC0000005(ACCESS_VIOLATION)で亡くなりました。私が何かをコンパイルすることができるかどうかは、打撃か逃している。誰もがこれを引き起こす原因を知っていますか?
次カーネルがエラーを再現します:
__global__ void gpu_kernel(int w, int h, RtmPoint *pPoints, int *pCounts)
{
__shared__ unsigned int test;
atomicInc(&test, 1000);
}
は第二に、共有メモリ上のミューテックスロックが含まれて私のコードは、GPUをハングアップし、私は理由を理解しない:例では
__device__ void lock(unsigned int *pmutex)
{
while(atomicCAS(pmutex, 0, 1) != 0);
}
__device__ void unlock(unsigned int *pmutex)
{
atomicExch(pmutex, 0);
}
__global__ void gpu_kernel_non_max_suppress(int w, int h, RtmPoint *pPoints, int *pCounts)
{
__shared__ RtmPoint localPoints[64];
__shared__ int localCount;
__shared__ unsigned int mutex;
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
int threadid = threadIdx.y * blockDim.x + threadIdx.x;
int blockid = blockIdx.y * gridDim.x + blockIdx.x;
if(threadid==0)
{
localCount = 0;
mutex = 0;
}
__syncthreads();
if(x<w && y<h)
{
if(some_test_on_pixel(x,y))
{
RtmPoint point;
point.x = x;
point.y = y;
// this is a local push_back operation
lock(&mutex);
if(localCount<64) // we should never get >64 points per block
localPoints[localCount++] = point;
unlock(&mutex);
}
}
__syncthreads();
if(threadid==0)
pCounts[blockid] = localCount;
if(threadid<localCount)
pPoints[blockid * 64 + threadid] = localPoints[threadid];
}
をコードthis siteで、共有メモリ上のアトミック操作を正常に使用できるようになりました。なぜ私のケースが機能しないのか混乱しています。私がロックとアンロックの行をコメントアウトすると、コードは正常に実行されますが、明らかに誤ってリストに追加されます。
アトミック操作やミューテックスロックの使用に関するパフォーマンス上の問題が懸念されているため、この問題がなぜ起こっているのか、おそらく目標を達成するためのより良い解決策があるかどうかに関するアドバイスをいただければ幸いです。
これは非常に興味深いものです。ありがとうございました。 – Robotbugs
私はこれを実装しようとしましたが、見つけたのはスキャン機能が正しくないということです。 "temp [pout * n + thid] + = temp [pin * n + thid-offset];"これは実際には「temp [pin * n + thid] = temp [pin * n + thid] + temp [pin * n + thid-offset];」です。 – Robotbugs
OK基本的に実装した内容を実装しました。後で最終コードを投稿します。どうもありがとう。 – Robotbugs