【发布时间】:2013-11-25 23:30:45
【问题描述】:
我有一个 CUDA 应用程序,它当前使用推力库在 GPU 上对向量进行求和和最大缩减。我发现对于某些向量长度,如果我将向量发送回主机并计算 C++ 中的总和和最大减少量,它会快得多。
总和和最大减少量应该在主机上是可矢量化的。主机上的内存是线性/连续的,我正在使用的编译器(GCC)支持它。鉴于我看到的时间,编译器似乎正在对代码进行矢量化,但我该如何确认呢?我没有任何强制编译器优化的经验,但我知道可以使用一些编译指示语句。 (不过,你会通过谷歌搜索找到很少的信息。)另外,我宁愿不去挖掘汇编来确认,因为我不会理解它。是否有编译器设置(在 GCC 或 NVCC 中)可用于在主机上强制矢量化或确认代码正在矢量化?
我为 sum 和 max reduction 编写的函数如下。 nvcc 编译器最终会编译它,因为函数包含 CUDA 代码。
void calc_vector_max_host(double& maxval, double *const vec_h, const double *const vec_d, int len)
{
//copy device vector to host
gpuErrchk(cudaMemcpy(vec_h, vec_d, len*sizeof(double), cudaMemcpyDeviceToHost));
//vectorized? max
maxval = *vec_h;
double* temp = vec_h;
for(int i = 1; i < len; i++, temp++)
{
if(*temp > maxval)
{
maxval = *temp;
}
}
}
void calc_vector_sum_host(double& sum, double *const vec_h, const double *const vec_d, int len)
{
//copy device vector to host
gpuErrchk(cudaMemcpy(vec_h, vec_d, len*sizeof(double), cudaMemcpyDeviceToHost));
//vectorized? sum
sum = 0.0;
double* temp = vec_h;
for(int i = 0; i < len; i++, temp++)
{
sum += *temp;
}
}
编辑:以下包含 gcc 自动矢量化所需的更正。还需要 cmets 中列出的编译器选项。
void calc_vector_max_host(double& maxval, double *const __restrict__ vec_h, const double *const __restrict__ vec_d, int len)
{
//copy device vector to host
gpuErrchk(cudaMemcpy(vec_h, vec_d, len*sizeof(double), cudaMemcpyDeviceToHost));
//vectorized? max
double local_maxval = vec_h[0];
for(int i = 1; i < len; i++)
{
double val = vec_h[i];
if(val > local_maxval)
{
local_maxval = val;
}
}
maxval = local_maxval;
}
void calc_vector_sum_host(double& sum, double *const __restrict__ vec_h, const double *const vec_d, int len)
{
//copy device vector to host
gpuErrchk(cudaMemcpy(vec_h, vec_d, len*sizeof(double), cudaMemcpyDeviceToHost));
//vectorized? sum
double local_sum = 0.0;
for(int i = 0; i < len; i++)
{
local_sum += vec_h[i];
}
sum = local_sum;
}
【问题讨论】: