Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cuda 为什么glm::dot比helper_math.h';s和我的实现 问题_Cuda_Glm Math - Fatal编程技术网

Cuda 为什么glm::dot比helper_math.h';s和我的实现 问题

Cuda 为什么glm::dot比helper_math.h';s和我的实现 问题,cuda,glm-math,Cuda,Glm Math,我在cuda中遇到了一些glm矩阵向量乘法的性能问题,记录在中(链接,因为它可能对其他人有用) 在做一些性能测试时,我发现glm的点积实现比cuda的helper_math.h实现更快 inline __host__ __device__ float dot(float4 a, float4 b) { return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; } 我试图模仿glm的实现,但性能保持不变: inline __host__ _

我在cuda中遇到了一些glm矩阵向量乘法的性能问题,记录在中(链接,因为它可能对其他人有用)

在做一些性能测试时,我发现glm的点积实现比cuda的helper_math.h实现更快

inline __host__ __device__ float dot(float4 a, float4 b)
{
   return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
}
我试图模仿glm的实现,但性能保持不变:

inline __host__ __device__ float dot(float4 a, float4 b)
{
   float4 tmp = a * b;
   return (tmp.x + tmp.y) + (tmp.z + tmp.w);
}
在我看来,这就是glm的实施:

template <typename T, precision P>
struct compute_dot<detail::tvec4, T, P>
{
    GLM_FUNC_QUALIFIER static T call(detail::tvec4<T, P> const & x, detail::tvec4<T, P> const & y)
    {
        detail::tvec4<T, P> tmp(x * y);
        return (tmp.x + tmp.y) + (tmp.z + tmp.w);
    }
};
结果 差别非常明显:

time for cuda glm (dot): 223 milliseconds
time for cuda helper math (dot): 307 milliseconds
测试方法 我使用以下内核进行测试(类似于glm、numElements 2000000、innerLoopSize 100)和std::chrono::high_resolution_时钟的测量

__global__ void cuDotKernel(const float4 *vectors, float4 *result, int numElements, int innerLoopSize) {
   int i = blockDim.x * blockIdx.x + threadIdx.x;
   if(i < numElements) {
       result[i] = vectors[i];
       if(i>1 && i < NUM_ELEMENTS - 1) {
           for(int j=0; j<innerLoopSize; j++) {
                result[i].y = dot(vectors[i+1], vectors[i]);
                result[i].x = dot(vectors[i-1], vectors[i]);
                result[i].z = dot(vectors[i+1], result[i]);
                result[i].w = dot(vectors[i-1], result[i]);
            }
        }
    }
}
\uuuu全局\uuuuu无效cuDotKernel(常量float4*向量、float4*结果、整数元素、整数innerLoopSize){
int i=blockDim.x*blockIdx.x+threadIdx.x;
如果(i1&&i对于(int j=0;j我以向量不会“爆炸”的方式更改了测试数据。这意味着它们保持在合理的范围[0.0-1000.0]。现在计时非常相似


cuda编译器似乎能够在glm的情况下优化某些计算,但在helper_math的情况下却无法优化。

尝试通过引用传递
参数,并尝试使用
\uuuuuForceInline\uuuuuuuu
限定符。变化不大,只有几毫秒。有时向上,有时向下,所以它没有什么意义。我知道ess编译器正在优化。这可能也是为什么我用
a*=b
编辑的版本没有改变任何东西的原因。重现问题的代码属于问题,而不是外部链接。imo在这种情况下,这只会扩大问题。此外,包含依赖项是不可行的,因此imo需要一个指向任何人都可以访问的repo的链接可以克隆甚至简单地下载更有用。但我还是要添加内核:)
__global__ void cuDotKernel(const float4 *vectors, float4 *result, int numElements, int innerLoopSize) {
   int i = blockDim.x * blockIdx.x + threadIdx.x;
   if(i < numElements) {
       result[i] = vectors[i];
       if(i>1 && i < NUM_ELEMENTS - 1) {
           for(int j=0; j<innerLoopSize; j++) {
                result[i].y = dot(vectors[i+1], vectors[i]);
                result[i].x = dot(vectors[i-1], vectors[i]);
                result[i].z = dot(vectors[i+1], result[i]);
                result[i].w = dot(vectors[i-1], result[i]);
            }
        }
    }
}