为什么glm :: dot比helper_math.h和我的实现更快

时间:2014-10-28 18:49:54

标签: cuda glm-math

问题

我在cuda中使用glm矩阵 - 向量乘法有一些性能问题,在bug tracker中有记录(链接因为它可能对其他人有用)。

在对它进行一些性能测试时,我发现,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);
    }
};

修改: 以下也没有改善性能:

inline __host__ __device__ float dot(float4 a, float4 b)
{
   a *= b;
   return (a.x + a.y) + (a.z + a.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_clock进行测量。

__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]);
            }
        }
    }
}

完整的测试代码位于bitbucket (the repo is public)it's possible to download directly (without hg)

我测试了Linux,CUDA 6.5,GeForce gtx 550ti和glm 0.9.5.4

问题

现在的问题是,为什么glm的实现速度更快?我怎样才能提高helper_maths的代码速度呢?

1 个答案:

答案 0 :(得分:2)

我以矢量不“爆炸”的方式更改了测试数据。意味着它们保持在合理的范围内[0.0 - 1000.0]。现在时间非常相似。

似乎cuda编译器能够在glm的情况下优化一些计算,但在helper_math的情况下不能。