簡體   English   中英

cuda 11.6 中的賦值運行極慢

[英]Assignment in cuda 11.6 running extremely slow

我正在 cuda 中測試定制的 Z 緩沖區 kernel。 簡而言之:檢查X個點是否在Y個多邊形內,並返回每個點的前多邊形 ID。 並行部分是用所有多邊形計算每個點。

整個過程沒有錯誤,它確實將數據傳輸到設備並將正確的結果返回給主機。

但是我在最后一行values[i] = val;中發現了巨大的時間消耗。

這個問題實際上很愚蠢。 我相信我在 kernel 中分配值的方法是錯誤的。 你能建議做這個任務的正確方法嗎?

非常感謝!

為了更好地理解 kernel 中的數據結構:

  • float* position_dist存儲:
  1. 首先是point0, point1, ... ,point(X-1)序列中的所有測試點 x,y,z
  2. 然后在poly0.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM