我的OpenCL测试的运行速度不超过CPU
My opencl test does not run much faster than CPU
我正在尝试测量GPU的执行时间,并将其与CPU进行比较。我编写了一个简单的_add函数,以添加简短的int矢量的所有元素。内核代码为:
global const int * A, global const uint * B, global int* C)
{
///------------------------------------------------
/// Add 16 bits of each
int AA=A[get_global_id(0)];
int BB=B[get_global_id(0)];
int AH=0xFFFF0000 & AA;
int AL=0x0000FFFF & AA;
int BH=0xFFFF0000 & BB;
int BL=0x0000FFFF & BB;
int CL=(AL+BL)&0x0000FFFF;
int CH=(AH+BH)&0xFFFF0000;
C[get_global_id(0)]=CH|CL;
}
我为此功能写了另一个CPU版本,在100个时间执行后,我的执行时间
clock_t before_GPU = clock();
for(int i=0;i<100;i++)
{
queue.enqueueNDRangeKernel(kernel_add,1,
cl::NDRange((size_t)(NumberOfAllElements/4)),cl::NDRange(64));
queue.finish();
}
clock_t after_GPU = clock();
clock_t before_CPU = clock();
for(int i=0;i<100;i++)
AddImagesCPU(A,B,C);
clock_t after_CPU = clock();
结果是在调用整个测量功能的10次之后的下文:
CPU time: 1359
GPU time: 1372
----------------
CPU time: 1336
GPU time: 1269
----------------
CPU time: 1436
GPU time: 1255
----------------
CPU time: 1304
GPU time: 1266
----------------
CPU time: 1305
GPU time: 1252
----------------
CPU time: 1313
GPU time: 1255
----------------
CPU time: 1313
GPU time: 1253
----------------
CPU time: 1384
GPU time: 1254
----------------
CPU time: 1300
GPU time: 1254
----------------
CPU time: 1322
GPU time: 1254
----------------
问题是我真的希望GPU比CPU快得多,但事实并非如此。我不明白为什么我的GPU速度不比CPU高。我的代码中有任何问题吗?这是我的GPU属性:
-----------------------------------------------------
------------- Selected Platform Properties-------------:
NAME: AMD Accelerated Parallel Processing
EXTENSION: cl_khr_icd cl_amd_event_callback cl_amd_offline_devices cl_khr_d3d10_sharing
VENDOR: Advanced Micro Devices, Inc.
VERSION: OpenCL 1.2 AMD-APP (937.2)
PROFILE: FULL_PROFILE
-----------------------------------------------------
------------- Selected Device Properties-------------:
NAME : ATI RV730
TYPE : 4
VENDOR : Advanced Micro Devices, Inc.
PROFILE : FULL_PROFILE
VERSION : OpenCL 1.0 AMD-APP (937.2)
EXTENSIONS : cl_khr_gl_sharing cl_amd_device_attribute_query cl_khr_d3d10_sharing
MAX_COMPUTE_UNITS : 8
MAX_WORK_GROUP_SIZE : 128
OPENCL_C_VERSION : OpenCL C 1.0
DRIVER_VERSION: CAL 1.4.1734
==========================================================
只是为了比较这是我的CPU规格:
------------- CPU Properties-------------:
NAME : Intel(R) Core(TM) i3-2100 CPU @ 3.10GHz
TYPE : 2
VENDOR : GenuineIntel
PROFILE : FULL_PROFILE
VERSION : OpenCL 1.2 AMD-APP (937.2)
MAX_COMPUTE_UNITS : 4
MAX_WORK_GROUP_SIZE : 1024
OPENCL_C_VERSION : OpenCL C 1.2
DRIVER_VERSION: 2.0 (sse2,avx)
==========================================================
我还使用QueryPerformanceCounter测量了壁时钟时间,这是结果:
CPU time: 1304449.6 micro-sec
GPU time: 1401740.82 micro-sec
----------------------
CPU time: 1620076.55 micro-sec
GPU time: 1310317.64 micro-sec
----------------------
CPU time: 1468520.44 micro-sec
GPU time: 1317153.63 micro-sec
----------------------
CPU time: 1304367.29 micro-sec
GPU time: 1251865.14 micro-sec
----------------------
CPU time: 1301589.17 micro-sec
GPU time: 1252889.4 micro-sec
----------------------
CPU time: 1294750.21 micro-sec
GPU time: 1257017.41 micro-sec
----------------------
CPU time: 1297506.93 micro-sec
GPU time: 1252768.9 micro-sec
----------------------
CPU time: 1293511.29 micro-sec
GPU time: 1252019.88 micro-sec
----------------------
CPU time: 1320753.54 micro-sec
GPU time: 1248895.73 micro-sec
----------------------
CPU time: 1296486.95 micro-sec
GPU time: 1255207.91 micro-sec
----------------------
我再次尝试了执行时间的OpenCL分析。
queue.enqueueNDRangeKernel(kernel_add,1,
cl::NDRange((size_t)(NumberOfAllElements/4)),
cl::NDRange(64),NULL,&ev);
ev.wait();
queue.finish();
time_start=ev.getProfilingInfo<CL_PROFILING_COMMAND_START>();
time_end=ev.getProfilingInfo<CL_PROFILING_COMMAND_END>();
一次执行一次的结果或多或少是相同的:
CPU time: 13335.1815 micro-sec
GPU time: 11865.111 micro-sec
----------------------
CPU time: 13884.0235 micro-sec
GPU time: 11663.889 micro-sec
----------------------
CPU time: 19724.7296 micro-sec
GPU time: 14548.222 micro-sec
----------------------
CPU time: 19945.3199 micro-sec
GPU time: 15331.111 micro-sec
----------------------
CPU time: 17973.5055 micro-sec
GPU time: 11641.444 micro-sec
----------------------
CPU time: 12652.6683 micro-sec
GPU time: 11632 micro-sec
----------------------
CPU time: 18875.292 micro-sec
GPU time: 14783.111 micro-sec
----------------------
CPU time: 32782.033 micro-sec
GPU time: 11650.444 micro-sec
----------------------
CPU time: 20462.2257 micro-sec
GPU time: 11647.778 micro-sec
----------------------
CPU time: 14529.6618 micro-sec
GPU time: 11860.112 micro-sec
ati rv730具有VLIW结构,因此最好尝试使用总线程为1/4的uint4
和int4
向量类型(这是numberOfleartess/16)。这也将有助于每个工作项目的内存加载速度更快。
与内存操作相比,内核也没有太多的计算。制作映射到RAM的缓冲区的性能会更好。不要复制数组,请使用MAP/UNMAP启动命令将它们映射到存储器。
如果它的速度不快,您可以同时使用GPU和CPU在上半场工作和下半部分工作以在%50期内完成。
也不要将克服循环放置。在循环结束后放置。这样,它将更快地加入它,并且已经具有固定执行,因此在完成第一个项目之前不会启动其他工作。我想这是固定队列,并在每个入口额外的开销后添加clfinish。最新核之后只有一个固执就足够了。
ATI RV730:64个VLIW单元,每个单元至少有4个流芯。750 MHz。
i3-2100:2个核心(仅用于反润滑的线)每个都具有同时流式传输8个操作的AVX。因此,这可以在飞行中进行16次操作。超过3 GHz。
简单地使用频率的流操作乘法:
ati rv730 = 192个单位(更多具有乘数函数,每个vliw的第5个元素)
i3-2100 = 48个单位
因此,gpu至少应为4倍(使用int4,uint4)。这是针对简单的ALU和FPU操作,例如位操作和乘法。特殊功能(例如trancandentals性能)可能会有所不同,因为它们仅在每个VLIW中的第5个单元上运行。
我进行了一些额外的测试,并意识到GPU已针对浮点操作进行了优化。我更改了以下测试代码:
void kernel simple_add(global const int * A, global const uint * B, global int* C)
{
///------------------------------------------------
/// Add 16 bits of each
int AA=A[get_global_id(0)];
int BB=B[get_global_id(0)];
float AH=0xFFFF0000 & AA;
float AL=0x0000FFFF & AA;
float BH=0xFFFF0000 & BB;
float BL=0x0000FFFF & BB;
int CL=(int)(AL*cos(AL)+BL*sin(BL))&0x0000FFFF;
int CH=(int)(AH*cos(AH)+BH*sin(BL))&0xFFFF0000;
C[get_global_id(0)]=CH|CL;
}
并得到了我所期望的结果(速度约10次):
CPU time: 741046.665 micro-sec
GPU time: 54618.889 micro-sec
----------------------------------------------------
CPU time: 741788.112 micro-sec
GPU time: 54875.666 micro-sec
----------------------------------------------------
CPU time: 739975.979 micro-sec
GPU time: 54560.445 micro-sec
----------------------------------------------------
CPU time: 755848.937 micro-sec
GPU time: 54582.111 micro-sec
----------------------------------------------------
CPU time: 724100.716 micro-sec
GPU time: 56893.445 micro-sec
----------------------------------------------------
CPU time: 744476.351 micro-sec
GPU time: 54596.778 micro-sec
----------------------------------------------------
CPU time: 727787.538 micro-sec
GPU time: 54602.445 micro-sec
----------------------------------------------------
CPU time: 731132.939 micro-sec
GPU time: 54710.000 micro-sec
----------------------------------------------------
CPU time: 727899.150 micro-sec
GPU time: 54583.444 micro-sec
----------------------------------------------------
CPU time: 727089.880 micro-sec
GPU time: 54594.778 micro-sec
----------------------------------------------------
对于较重的浮点操作如下:
void kernel simple_add(global const int * A, global const uint * B, global int* C)
{
///------------------------------------------------
/// Add 16 bits of each
int AA=A[get_global_id(0)];
int BB=B[get_global_id(0)];
float AH=0xFFFF0000 & AA;
float AL=0x0000FFFF & AA;
float BH=0xFFFF0000 & BB;
float BL=0x0000FFFF & BB;
int CL=(int)(AL*(cos(AL)+sin(2*AL)+cos(3*AL)+sin(4*AL)+cos(5*AL)+sin(6*AL))+
BL*(cos(BL)+sin(2*BL)+cos(3*BL)+sin(4*BL)+cos(5*BL)+sin(6*BL)))&0x0000FFFF;
int CH=(int)(AH*(cos(AH)+sin(2*AH)+cos(3*AH)+sin(4*AH)+cos(5*AH)+sin(6*AH))+
BH*(cos(BH)+sin(2*BH)+cos(3*BH)+sin(4*BH)+cos(5*BH)+sin(6*BH)))&0xFFFF0000;
C[get_global_id(0)]=CH|CL;
}
结果或多或少相同:
CPU time: 3905725.933 micro-sec
GPU time: 354543.111 micro-sec
-----------------------------------------
CPU time: 3698211.308 micro-sec
GPU time: 354850.333 micro-sec
-----------------------------------------
CPU time: 3696179.243 micro-sec
GPU time: 354302.667 micro-sec
-----------------------------------------
CPU time: 3692988.914 micro-sec
GPU time: 354764.111 micro-sec
-----------------------------------------
CPU time: 3699645.146 micro-sec
GPU time: 354287.666 micro-sec
-----------------------------------------
CPU time: 3681591.964 micro-sec
GPU time: 357071.889 micro-sec
-----------------------------------------
CPU time: 3744179.707 micro-sec
GPU time: 354249.444 micro-sec
-----------------------------------------
CPU time: 3704143.214 micro-sec
GPU time: 354934.111 micro-sec
-----------------------------------------
CPU time: 3667518.628 micro-sec
GPU time: 354809.222 micro-sec
-----------------------------------------
CPU time: 3714312.759 micro-sec
GPU time: 354883.888 micro-sec
-----------------------------------------
- 整数不会重复超过随机数
- C++问题:用户认为数字1-100,程序提出问题不超过6次即可得到答案。无法正确
- 学习多线程C++:添加线程不会使执行速度更快,即使它看起来应该
- 在C++中使用并行化的预期速度是多少(不是 OpenMp,而是 <thread>)
- 是否有一个 std::set 函数来确定不超过数字 x 的最大元素?
- 为什么使用 .replace 运算符时字符串的长度不超过 16 个字符?
- 我们如何有证据表明,声明虚拟函数的类是2个字节,其中一个不超过一个未声明,而在子类中
- 我的OpenCL测试的运行速度不超过CPU
- 如何在C 中修复执行速度不一致
- 我试图创建进程的二叉树结构,其中每个进程不超过 2 个子进程
- 如何使变量不超过其类型的大小限制
- 如何在2D数组中搜索以确保不超过3个连续字符
- 在 N 个元素的数组中求出"P"元素的最小和,以便一起选择不超过"k"个连续元素
- 写下 2 的所有幂不超过给定的数字
- QString参数中的参数不超过9个?如何处理
- 使用AVIStreamWrite创建的AVI的长度和播放速度不正确
- 在不超过y次递归的情况下,一个数可以被提升到的最大功率
- 鼠标速度不改变使用spi_setmousspeed
- C++相机的速度不是预期的
- 通过删除不超过一个元素来排序数组的识别可能性