我试图通过将来自命令行参数的值传递给内核来使 Cuda 应用程序更具动态性。
该应用程序调用多个内核,并最大化块和网格大小。当我尝试运行应用程序时,我得到以下结果:
- 硬编码值:0.96 秒
- 在内核初始化时传递一个值:3.48 秒
- 声明 a
__device__ int
,并将其设置为值:3.48 秒
一旦在执行时输入该值,它将在程序的其余部分保持不变。
这两个 3.48 秒时间来自对变量本身的访问。如果我用硬编码的整数替换变量,运行时间会大大缩短。这个值被非常频繁地访问,我想知道是否有办法保持与硬编码值相似的速度,但降低访问变量的成本。是否可以通过使用变量来加快速度?
慢 3.6 倍重要吗?有点。这只是一小部分更大的东西。
任何帮助将不胜感激。
*运行 2.0 硬件。
编辑:这是我遇到的差异的一个例子:
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <ctime>
using namespace std;
clock_t start;
__device__ int x;
__global__ void setNum(int i)
{
x = i;
return;
}
__device__ void d_swap(int * a, int * b)
{
int temp = *a;
*a = *b;
*b = temp;
}
__device__ void other(int n, int * vec)
{
int i;
for(i = 0; i < n; ++i) vec[i] = i;
for (int j = 0; j < 5; j++)
for(i = 1; i < n-1; ++i)
d_swap(&vec[i], &vec[i-1]);
}
__global__ void Pressure(int i)
{
int a[12];
other(x, a);
//other(12,a);
}
int main(int argc, char * argv[])
{
if (argc != 2)
{
fprintf(stderr,"Invalid number of arguments.\n");
exit(1);
}
int num = atoi(argv[1]);
cudaSetDevice(1);
cudaMemset(&x, num, sizeof(int));
setNum<<< 1 , 1>>>( num );
cudaError_t cuda_status = cudaDeviceSynchronize();
if (cuda_status != cudaSuccess) {
printf("No dice\n");
exit(1);
}
int results = 0;
cudaMemcpyFromSymbol(&results, x, sizeof(int));
printf("Value of x: %i\n", results);
start = clock();
for (int i = 0; i < 8; i++)
Pressure<<<65535, 1024>>>(i);
cuda_status = cudaDeviceSynchronize();
printf("Result: %f\n", (float)(clock()-start)/CLOCKS_PER_SEC);
return 0;
}
编译:nvcc -m64 -gencode arch=compute_20,code=sm_20 -o test test.cu
运行:./test 12
(12 设置 x 变量)
注意注释掉的代码块:
跑步other(x, a);
,我得到1.370000
跑步other(12,a);
,我得到0.020000