我正在编写一个函数来处理很多 BLAS gemv 操作。
我希望能够在 GPU 上执行此操作,并且我已尝试使用 cuBlas。
我的问题是我的矩阵和 vector 相当小,100x100 矩阵和 100 vector 。与 CPU 相比,CuBlas 需要很长时间,我知道为什么,CPU 上的快速缓存和调用 GPU 的大量开销混合在一起。
因此,我正在尝试找出一种聪明的方法来测量将调用传递给 GPU 所需的时间。
这是 CUDA 设置调用并将其发送到图形处理器所花费的时间——不包括执行矩阵 vector 乘法实际花费的时间。
我该怎么做?
最佳答案
更新:以下结果是针对 2005 硬件(nVidia 7800 GTX)上的手写 FFT GPU 算法,但显示了 CPU-GPU 传输瓶颈的原理
开销不是调用本身,而是 GPU 程序的编译和 GPU 与主机之间的数据传输。 CPU 针对可完全在高速缓存中执行的功能进行了高度优化,并且 DDR3 内存的延迟远低于为 GPU 提供服务的 PCI-Express 总线。我在编写 GPU FFT 例程(在 CUDA 之前)时亲身经历过这一点。请看this related question .
N FFTw (ms) GPUFFT (ms) GPUFFT MFLOPS GPUFFT Speedup 8 0 0.06 3.352705 0.006881 16 0.001 0.065 7.882117 0.010217 32 0.001 0.075 17.10887 0.014695 64 0.002 0.085 36.080118 0.026744 128 0.004 0.093 76.724324 0.040122 256 0.007 0.107 153.739856 0.066754 512 0.015 0.115 320.200892 0.134614 1024 0.034 0.125 657.735381 0.270512 2048 0.076 0.156 1155.151507 0.484331 4096 0.173 0.215 1834.212989 0.804558 8192 0.483 0.32 2664.042421 1.510011 16384 1.363 0.605 3035.4551 2.255411 32768 3.168 1.14 3450.455808 2.780041 65536 8.694 2.464 3404.628083 3.528726 131072 15.363 5.027 3545.850483 3.05604 262144 33.223 12.513 3016.885246 2.655183 524288 72.918 25.879 3079.443664 2.817667 1048576 173.043 76.537 2192.056517 2.260904 2097152 331.553 157.427 2238.01491 2.106081 4194304 801.544 430.518 1715.573229 1.861814
上表显示了基于内核大小的 GPU FFT 实现与 CPU 实现的时序。对于较小的尺寸,向/从 GPU 传输数据占主导地位。较小的内核可以在 CPU 上执行,一些实现/大小完全在缓存中。这使得 CPU 成为小型操作的最佳选择。
另一方面,如果您需要以最少的进出 GPU 的移动量对数据执行大量工作,那么 GPU 将轻而易举地击败 CPU。
就衡量示例中的效果而言,我建议执行与上述类似的实验。尝试计算出为每种大小的矩阵计算的 FLOPS,并针对不同大小的矩阵在 CPU 和 GPU 上运行测试。将 GPU 与 CPU 的大小、时间和 FLOPS 输出到 CSV 文件。对于任何分析,请确保您运行代码的数百次迭代并对整个过程进行计时,然后将总时间除以迭代次数以获得循环时间。如果您的算法允许,也可以尝试不同形状的矩阵(例如 10x100 而不是 100x10)。
使用此数据,您可以了解间接费用是多少。要找出完全相同的实验,但将在 GPU 上执行的内部着色器代码替换为无操作(只需从输入复制到输出)。
希望对您有所帮助,
关于c++ - OpenCL 或 CUDA 调用的开销?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8985470/