qiu*_*989 2 c c++ cuda fft visual-studio-2012
基本上我想通过将 cuFFT 执行函数放在 for 循环中来测量 cuFFT 函数的时间成本,这是我第一次使用的代码(这是 Nvidia 网站中用于 CUDA 的简单示例):
顺便说一下,我的CPU是Intel I7-3630QM 2.40GHz,GPU是Nvidia NVS 5200M。我使用的平台是Visual Studio 2012和CUDA 5.5,操作系统是Windows 7,64位。
#include "cuda_runtime.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <cufft.h>
#include <cuda.h>
#include <cuda_runtime_api.h>
#define NX 1024
#define NY 1024
int main(int argc, char** argv) {
int i;
int Iter;
cufftHandle plan;//A data structure named plan containing all information needed for Fourier Transform.
cufftComplex *data1;//data structure to store the real value and complex value of the input and output of Fourier Transform.
cudaMalloc((void**)&data1, sizeof(cufftComplex)*NX*NY);//Prepare the NX*NY 2D Fourier Transform by alloc input values on GPU Memory
cufftPlan2d(&plan, NX, NY, CUFFT_C2C);//Prepare 2D Fourier Transform (NX*NY), type is C2C that is complex to complex.
Iter = 1000;
clock_t begin, end;
double cost;
begin = clock();
for (i = 0;i <Iter;i++){
cufftExecC2C(plan, data1, data1, CUFFT_FORWARD);//Execute the Fourier Transform with input data in data1 and output result to data1, CUFFT_FORWARD means it is FFT not iFFT.
}
end = clock();
cost = (double)(end - begin) / CLOCKS_PER_SEC;
printf("%lf seconds\n", cost);
cufftDestroy(plan);
cudaFree(data1);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这个程序返回的时间一般是0.030s,如果我把Iter的值(循环多少)改成1100,结果变成了0.033s,如果Iter=1200,结果是0.036s,看起来是线性的。
这一直保持正确,直到 Iter = 1500,Iter = 1500 时的时间为 0.195s,当 Iter = 1600 时,时间 = 0.431s。
我不明白为什么时间成本是这样的,任何人都可以帮助我吗?
先感谢您。
修改你的代码如下:
cudaDeviceSynchronize(); // add this line
end = clock();
Run Code Online (Sandbox Code Playgroud)
我相信你会得到理智的结果。
CUFFT 函数是异步的,因此它们可以支持复制和计算的流式重叠。这意味着它们在底层 GPU 操作完成之前返回。因此,您的 for 循环实际上是将大量要一个接一个执行的转换排队。但它们不一定在您完成计时时完成。您正在观察的复杂行为我认为与超出可以排队的内核启动数量的内部队列深度有关,在其他请求必须等待队列插槽打开之前。但这不是中心问题。
核心问题是你的计时方法有缺陷。这只是使用基于主机的计时方法来计时异步 GPU 活动所固有的危险的另一个例子。