Visual c++ 如何快速识别三角形和圆形框是否重叠

Visual c++ 如何快速识别三角形和圆形框是否重叠,visual-c++,gpgpu,Visual C++,Gpgpu,这里我想做的是确定一组二维三角形中哪个三角形的长方体与圆的长方体重叠。未重叠的三角形将指定给-1,否则将指定给它自己的索引 三角形的顶点存储在一个推力向量中。d_pTriXys是指向向量的原始指针。每个三角形指向顶点数组索引的3个索引存储在另一个设备向量中。d_ptriindex是指向此向量的原始指针。triNum是三角形的计数 代码是在VisualStudioC++中完成的,它工作。但性能似乎是个问题。对于使用550万个三角形和280万个顶点检查2225个圆的情况,大约需要3.5秒。它没有我希

这里我想做的是确定一组二维三角形中哪个三角形的长方体与圆的长方体重叠。未重叠的三角形将指定给-1,否则将指定给它自己的索引

三角形的顶点存储在一个推力向量中。d_pTriXys是指向向量的原始指针。每个三角形指向顶点数组索引的3个索引存储在另一个设备向量中。d_ptriindex是指向此向量的原始指针。triNum是三角形的计数

<>代码是在VisualStudioC++中完成的,它工作。但性能似乎是个问题。对于使用550万个三角形和280万个顶点检查2225个圆的情况,大约需要3.5秒。它没有我希望的那么快。有人有什么想法来改进算法以获得更好的性能吗

我试图更改寄存器计数,threadsPerBlock。现在的环境似乎是最好的

  // RangeAlgo.h

  struct tagXy_f
  {
     float x;
     float y;
  };


  CUDA_HOST_DEV __forceinline bool IsCircleAndTriangleBoxesSeparated(
     const tagXy_f triVertices[3], const tagXy_f &circleCen, float circleRad)
  {

     float t = min(triVertices[0].x, min(triVertices[1].x, triVertices[2].x));
     if (circleCen.x <= t - circleRad)
        return true;

     t = max(triVertices[0].x, max(triVertices[1].x, triVertices[2].x));
     if (circleCen.x >= t + circleRad)
        return true;

     t = min(triVertices[0].y, min(triVertices[1].y, triVertices[2].y));
     if (circleCen.y <= t - circleRad)
        return true;

     t = max(triVertices[0].y, max(triVertices[1].y, triVertices[2].y));
     return (circleCen.y >= t + circleRad);
  }


  // Main.cpp

  __global__ void MarkOutTrianglesKernel(const uint3 *d_pTriIndices, unsigned triNum,
     const float2 *d_pTriXys, const tagXy_f &d_circleCen, float circleRad,
     int *d_pValidTriIndices)
  {
     unsigned tid = blockIdx.x * blockDim.x + threadIdx.x;

     if (tid < triNum)
     {
        const uint3 &triInds = d_pTriIndices[tid];
        // to local variable/registers, make it faster
        const float2 triVertices[3] = { d_pTriXys[triInds.x],
        d_pTriXys[triInds.y], d_pTriXys[triInds.z] };

        bool b = IsCircleAndTriangleBoxesSeparated(reinterpret_cast<const tagXy_f *>(triVertices),
               d_circleCen, circleRad);

        d_pValidTriIndices[tid] = b ? -1 : (int)tid;
     }
  }


  void main()
  {
     // here is the sample code to check one circle with all triangles
     uint3 *d_pTriIndices;      // indices of all triangles
     unsigned triNum;           // count of triangles
     const float2 *d_pTriXys;   // all vertices of triangles
     tagXy_f d_circleCen;
     float circleRad;
     int *d_pValidTriIndices;

     ...

     int threadsPerBlock = 256;
     int blocksPerGrid = (int)((triNum + threadsPerBlock - 1) / threadsPerBlock);

     MarkOutTrianglesKernel<<<blocksPerGrid, threadsPerBlock>>>(d_pTriIndices, triNum,
        d_pTriXys, d_circleCen, circleRad, d_pValidTriIndices);

     ...
  }
//RangeAlgo.h
结构tagXy\u f
{
浮动x;
浮动y;
};
CUDA_主机_开发__强制内联布尔是独立的圆形三角形框(
常数tagXy_f三顶点[3],常数tagXy_f&圈,浮点圈)
{
float t t=min(三顶点[0].x,min(三顶点[1].x,三顶点[2].x));
if(圆x=t+circleRad)
返回true;
t=min(三顶点[0].y,min(三顶点[1].y,三顶点[2].y));
if(圆y=t+circleRad);
}
//Main.cpp
__全局无效MarkOutTrianglesKernel(常量uint3*d_ptriIndex,无符号三分式,
常数浮点数2*d_pTriXys,常数tagXy_f&d_循环,浮点数循环,
int*d_pvalidtriindex)
{
无符号tid=blockIdx.x*blockDim.x+threadIdx.x;
if(tid
我是否正确理解必须为每个圆调用内核?那么运行时对我来说似乎并不太糟糕。但这总是相对的,如果不知道您使用的是哪种硬件,就无法判断。(顺便说一句,这更像是一个问题…)是的,每个圆都调用内核。我的二维三角形和圆来自旋转的三维三角形和圆柱体。很可能,某些圆柱体具有相同的方向。所以我修改了我的“标记”函数,允许在加载三角形顶点后检查多个圆。还使用二维三角形顶点的XY阵列的不同阵列。所有这些改进都将时间从5秒缩短到了2.6秒。至少在大多数圆柱体的方向相同的情况下,它仍有改进的余地。计算机:Inter i7-8700K CPU@3.7GHz,32GB。图形卡:GTX1070。因此,您的GPU的最大带宽为256GB/s。作为一个简单的估计,顶点加载数的最坏情况是
2225*5.5m*3
,您存储
2225*5.5m
标记,总计440.55GB,并以最小1.72s的速度占用您的GPU。因此,您将达到最大性能的66%——假设您具有完全合并的内存访问。我认为您应该开始调查实际加载顶点的频率,以及是否可以以某种方式保存加载(这完全取决于输入)。如果您知道每个循环只有几个重叠,那么您可能可以保存许多存储。我是否正确理解您必须为每个循环调用内核?那么运行时对我来说似乎并不太糟糕。但这总是相对的,如果不知道您使用的是哪种硬件,就无法判断。(顺便说一句,这更像是一个问题…)是的,每个圆都调用内核。我的二维三角形和圆来自旋转的三维三角形和圆柱体。很可能,某些圆柱体具有相同的方向。所以我修改了我的“标记”函数,允许在加载三角形顶点后检查多个圆。还使用二维三角形顶点的XY阵列的不同阵列。所有这些改进都将时间从5秒缩短到了2.6秒。至少在大多数圆柱体的方向相同的情况下,它仍有改进的余地。计算机:Inter i7-8700K CPU@3.7GHz,32GB。图形卡:GTX1070。因此,您的GPU的最大带宽为256GB/s。作为一个简单的估计,顶点加载数的最坏情况是
2225*5.5m*3
,您存储
2225*5.5m
标记,总计440.55GB,并以最小1.72s的速度占用您的GPU。因此,您将达到最大性能的66%——假设您具有完全合并的内存访问。我认为您应该开始调查实际加载顶点的频率,以及是否可以以某种方式保存加载(这完全取决于输入)。如果您知道每个循环只有几个重叠,那么您可能可以节省许多存储。