CUDA性能-始终返回不同的值
这是我的代码:CUDA性能-始终返回不同的值,cuda,Cuda,这是我的代码: using namespace std; #include <iostream> #include <stdio.h> #include <stdlib.h> const int N = 8000; void fillArray(int *data, int count) { for (int i = 0; i < count; i++) data[i] = rand() % 100; } __global_
using namespace std;
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
const int N = 8000;
void fillArray(int *data, int count) {
for (int i = 0; i < count; i++)
data[i] = rand() % 100;
}
__global__ void add(int* a, int *b, int *c) {
int tid = threadIdx.x + blockIdx.x * blockDim.x;
if (tid < N) {
c[tid] = a[tid] + b[tid];
}
}
__global__ void subtract(int* a, int *b, int *c) {
int tid = threadIdx.x + blockIdx.x * blockDim.x;
if (tid < N) {
c[tid] = a[tid] - b[tid];
}
}
__global__ void multiply(int* a, int *b, int *c) {
int tid = threadIdx.x + blockIdx.x * blockDim.x;
if (tid < N) {
c[tid] = a[tid] * b[tid];
}
}
__global__ void divide(int* a, int *b, int *c) {
int tid = threadIdx.x + blockIdx.x * blockDim.x;
if (tid < N) {
c[tid] = a[tid] / b[tid];
}
}
__global__ void modu(int* a, int *b, int *c) {
int tid = threadIdx.x + blockIdx.x * blockDim.x;
if (tid < N) {
c[tid] = a[tid] % b[tid];
}
}
__global__ void neg(int *data, int *c) {
int tid = threadIdx.x + blockIdx.x * blockDim.x;
if (tid < N) {
c[tid] = -data[tid];
}
}
float duration(int *devA, int *devB, int *devC, int blocksPerGrid, int threadsPerBlock) {
cudaEvent_t start, stop;
float elapsedTime;
cudaEventCreate(&start);
cudaEventCreate(&stop);
cudaEventRecord(start, 0);
int hArrayC[N];
add<<<blocksPerGrid, threadsPerBlock>>>(devA, devB,devC);
cudaMemcpy(hArrayC,devC,N*sizeof(int),cudaMemcpyDeviceToHost);
subtract<<<blocksPerGrid, threadsPerBlock>>>(devA, devB,devC);
cudaMemcpy(hArrayC,devC,N*sizeof(int),cudaMemcpyDeviceToHost);
multiply<<<blocksPerGrid, threadsPerBlock>>>(devA, devB,devC);
cudaMemcpy(hArrayC,devC,N*sizeof(int),cudaMemcpyDeviceToHost);
divide<<<blocksPerGrid, threadsPerBlock>>>(devA, devB,devC);
cudaMemcpy(hArrayC,devC,N*sizeof(int),cudaMemcpyDeviceToHost);
modu<<<blocksPerGrid, threadsPerBlock>>>(devA, devB,devC);
cudaMemcpy(hArrayC,devC,N*sizeof(int),cudaMemcpyDeviceToHost);
neg<<<blocksPerGrid, threadsPerBlock>>>(devA,devC);
cudaMemcpy(hArrayC,devC,N*sizeof(int),cudaMemcpyDeviceToHost);
neg<<<blocksPerGrid, threadsPerBlock>>>(devB,devC);
cudaMemcpy(hArrayC,devC,N*sizeof(int),cudaMemcpyDeviceToHost);
cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
cudaEventElapsedTime(&elapsedTime, start, stop);
cudaEventDestroy(start);
cudaEventDestroy(stop);
return elapsedTime;
}
int main(void) {
int *a, *b;
a = new int[N];
b = new int [N];
float dur = 0;
int *devA, *devB,*devC;
cudaMalloc((void**) &devA, N * sizeof(int));
cudaMalloc((void**) &devB, N * sizeof(int));
cudaMalloc((void**) &devC, N * sizeof(int));
fillArray(a, N);
fillArray(b, N);
cudaMemcpy(devA, a, N * sizeof(int), cudaMemcpyHostToDevice);
cudaMemcpy(devB, b, N * sizeof(int), cudaMemcpyHostToDevice);
dur = duration(devA, devB, devC,N, 1);
cout << "Global memory version:\n";
cout << "Process completed in " << dur;
cout << " for a data set of " << N << " integers.";
cudaFree(devA);
cudaFree(devB);
delete [] a;
delete [] b;
return 0;
}
使用名称空间std;
#包括
#包括
#包括
const int N=8000;
无效填充数组(整数*数据,整数计数){
for(int i=0;i 这可能是由于英伟达驱动程序的加载/卸载引起的,将其视为GPU的初始化步骤。< /P>
您可以将GPU设置为持久化模式:
nvidia-smi -pm 1
或者,您可以在对GPU代码计时以触发驱动程序加载之前运行虚拟内核:
__global__ void dummy()
{
// This kernel does nothing, this is just a "warm-up"
}
// Before your cudaEventRecord etc.
dummy<<<blocksPerGrid, threadsPerBlock>>>();
\uuuu全局\uuuuu无效虚拟()
{
//这个内核什么都不做,这只是一个“预热”
}
//在你的考试之前等等。
dummy();
或者在对内核进行计时之前使用cudaThreadSynchronize()
。首先,如果您使用nvprof
,您的生活会更轻松。其次,您应该阅读此问题的注释:。尝试将GPU设置为持久化模式(nvidia smi-pm 1
)。我知道,但我必须这样做。您可以尝试在正在计时的内核之前调用一个虚拟内核,因此驱动程序加载的开销不应影响您的计时。我可以通过编程解决这个问题吗?您能给我们提供您系统的更多规格吗?哪个gpu用于哪个操作系统。您的代码是每个块只启动一个线程。这有什么诀窍,但会造成性能漏洞。请尝试每个块启动更多线程,例如125个块,每个块调用64个线程。最后释放devC以进行良好的清理。nvprof
的结果如何?它们是否始终一致?您的机器配置是什么?什么类型的GPU ar你在使用什么?这是windows还是linux?GPU也在运行显示器吗?你在使用哪个驱动程序和CUDA版本?当我运行你的代码时,我得到的结果是0.76左右。我从来没有看到过10、20或30。因为你在计时序列中运行多个内核,所以显示器驱动程序可能会短暂地将GPU带到p执行显示任务,这可能会显示在您的计时中。我认为,如果您使用开始点和停止点分别计时每个内核,并将经过的时间相加,您将看到较少的变化。