我跟着http://code.google.com/p/stanford-cs193g-sp2010/和在线发布的视频讲座,做了一个问题集(第一个)我遇到了一些有点违反直觉的问题,至少问题的方式是问。这个问题要求我在cpu和gpu上推导一个执行时间的时序模型,假设基于我自己机器上运行的示例应用程序的时序进行线性缩放。
- 插入您计算机上的代码打印的时间数字 研究这个等式并报告收支平衡点 (当cpu版本与gpu版本一样快时)将是。
我遇到的问题是我的内核比等效函数的主机版本花了更长的时间(我将在下面发布),这样就没有收支平衡点了。我得到的数字如下。
done with copy to gpu kernel
copy to gpu took 26.30630 ms
done with gpu shift cypher kernel
gpu shift cypher took 7.33203 ms
done with copy from gpu kernel
copy from gpu took 28.54141 ms
host shift cypher took 0.00186 ms
Worked! CUDA and reference output match.
你觉得我做事的方式有问题吗?这是内核和主机函数。
// This kernel implements a per element shift
__global__ void shift_cypher(unsigned int *input_array, unsigned int *output_array,
unsigned int shift_amount, unsigned int alphabet_max, unsigned int array_length)
{
int gid = blockIdx.x * blockDim.x + threadIdx.x;
output_array[gid] = (input_array[gid] + shift_amount)%(alphabet_max+1);
}
void host_shift_cypher(unsigned int *input_array, unsigned int *output_array, unsigned int shift_amount, unsigned int alphabet_max, unsigned int array_length)
{
for(unsigned int i=0;i<array_length;i++)
{
int element = input_array[i];
int shifted = element + shift_amount;
if(shifted > alphabet_max)
{
shifted = shifted % (alphabet_max + 1);
}
output_array[i] = shifted;
}
}
示例应用程序使用16MB的整数元素运行,块大小为512.以下是有问题的文件的完整源代码http://pastebin.com/htYH0bA2
答案 0 :(得分:2)
主机移位密码耗时0.00186毫秒
这看起来很奇怪。无论你在CPU上使用16MB做什么,它都需要花费超过一毫秒的时间。
通过查看pastebin代码,您似乎可以使用CUDA事件计算所有内容。虽然我没有使用它们,但我猜测你用它来测量GPU内核执行的实际时间。其中,在刚刚调用主机代码的情况下几乎没有。这真的是他们如何衡量在斯坦福大学课程中执行的主持人代码吗?
你可以通过任何类型的C计时器检查这个结果来证明我的错误。
答案 1 :(得分:0)
这是计时器的一个问题,正如w.m指出的那样。我相信,问题是定时器中的事件记录功能在记录事件之前将控制权交给基于cpu的主机功能。这有点令人困惑,因为你会认为记录事件会在主机代码执行的时间内发生但看起来它更像是在主机代码执行完毕后同时记录启动和停止事件。将cudaThreadSynchronize();
添加到启动计时器似乎可以解决问题(确保在继续使用主机代码之前记录事件。这可能是Windows唯一的差异或基于我的CUDA版本或硬件等我不确定无论如何,我的新的,更正常的结果如下。
done with copy to gpu kernel
copy to gpu took 25.75683 ms
done with gpu shift cypher kernel
gpu shift cypher took 7.45667 ms
done with copy from gpu kernel
copy from gpu took 29.10922 ms
host shift cypher took 153.98772 ms
1 second sleep took 999.85291 ms
Worked! CUDA and reference output match.