[英]Assignment in cuda 11.6 running extremely slow
我正在 cuda 中測試定制的 Z 緩沖區 kernel。 簡而言之:檢查X
個點是否在Y
個多邊形內,並返回每個點的前多邊形 ID。 並行部分是用所有多邊形計算每個點。
整個過程沒有錯誤,它確實將數據傳輸到設備並將正確的結果返回給主機。
但是我在最后一行values[i] = val;
中發現了巨大的時間消耗。
這個問題實際上很愚蠢。 我相信我在 kernel 中分配值的方法是錯誤的。 你能建議做這個任務的正確方法嗎?
非常感謝!
為了更好地理解 kernel 中的數據結構:
float* position_dist
存儲:point0, point1, ... ,point(X-1)
序列中的所有測試點 x,y,zpoly0.p0, dist0, poly0.p1, dist0, poly0.p2, dist0, poly0.p3, dist0, ... , poly(Y-1).p0, dist(Y-1), poly(Y-1).p1, dist(Y-1), poly(Y-1).p2, dist(Y-1), poly(Y-1).p3, dist(Y-1)
。 因此,每個多邊形在偏移時有 16 個值。int* values
存儲:默認值為 -1。 它將更新為polyID
並返回給主機。CUDA_GLOBAL void computeOcclusion_kernel(float* position_dist, int* values, int numPt, int numPositions)
{
uint i = blockIdx.x * blockDim.x + threadIdx.x;
if (i < numPt && i % 3 == 0)
{
Point pt(position_dist[i + 0], position_dist[i + 1], position_dist[i + 2]);
uint offset = numPt - i;
float dist = 10000000;
int val = -1;
for (int o = i; o < i + numPositions; o += 16)
{
int j = o + offset;
int polyID = (j - numPt) / 16;
Point p0(position_dist[j + 0], position_dist[j + 1], position_dist[j + 2]);
Point p1(position_dist[j + 4], position_dist[j + 5], position_dist[j + 6]);
Point p2(position_dist[j + 8], position_dist[j + 9], position_dist[j + 10]);
Point p3(position_dist[j + 12], position_dist[j + 13], position_dist[j + 14]);
if (position_dist[j + 3] < dist)
{
if(inPoly(pt,p0,p1,p2,p3))
{
val = polyID;
dist = position_dist[j + 3];
}
}
}
values[i] = val;
}
}
感謝阿金的評論。 我通過使用連續的 memory 位置和動態共享內存重組了 kernel。
它現在工作正常。
CUDA_GLOBAL void computeOcclusion_kernel(float* position_dist, int* values, int numPt, int numPositions)
{
extern __shared__ int shared[];
for (uint i = blockIdx.x * blockDim.x + threadIdx.x;
i < numPt/ 3;
i += blockDim.x * gridDim.x)
{
uint t = i * 3;
Point pt(position_dist[t + 0], position_dist[t + 1], position_dist[t + 2]);
uint offset = numPt - t;
float dist = 10000000;
shared[i] = -1;
for (int o = i; o < t + numPositions; o += 16)
{
int j = o + offset;
int polyID = (j - numPt) / 16;
Point p0(position_dist[j + 0], position_dist[j + 1], position_dist[j + 2]);
Point p1(position_dist[j + 4], position_dist[j + 5], position_dist[j + 6]);
Point p2(position_dist[j + 8], position_dist[j + 9], position_dist[j + 10]);
Point p3(position_dist[j + 12], position_dist[j + 13], position_dist[j + 14]);
if (position_dist[j + 3] < dist)
{
if(inPoly(pt,p0,p1,p2,p3))
{
shared[i] = polyID;
dist = position_dist[j + 3];
}
}
}
__syncthreads();
buffervalues[i] = shared[i];
}
}
還需要在 kernel 啟動中聲明動態共享 memory 大小。
computeOcclusion_kernel <<< grid, block, NUM_BUFFER/3*sizeof(int) >>>...
但是,動態共享 memory 大小只能是我所理解的最大 48kb - 在這種情況下,我的緩沖區大小僅適用於 48KB/sizeof(int) = 1200。
這比我要求的要少得多。 我需要類似:buffer_X * buffer_Y * 4 = 4MB。
我將研究這樣做的替代策略。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.