国产嵌入式GPGPU-soc的开发多使用opencl,开发时需要在Windows下搭建GPU计算的测试框架,用以对算法实现进行测试。在Windows平台下利用方便的开发工具对算法进行基本实现和调试,然后就能方便在soc上进行调试。
开发环境:
两台笔记本:
CPU均是i9-12900H 2.50 GHz,带有核心显卡Iris Xe
GPU分别为:RTX 3070 ti、RTX 3060
在Windows下开发C++要想代码接近soc的环境,所以选用mingw64编译器。安装cuda后,把cuda中的opencl头文件和OpenCL.lib复制到工程目录,在makefile中引用即可。
在mingw下使用clFFT就需要配置一下。首先下载clfft的源码,下载cmake-Windows版。
默认使用的是vc,在命令行中改为mingw编译器:
cmake ../src -G "MinGW Makefiles" -D CMAKE_MAKE_PROGRAM=/mingw64/bin/make.exe -D CMAKE_C_COMPILER=gcc -D CMAKE_CXX_COMPILER=g++
注意不能有中文路径。
clFFT编译完了把头文件复制到工程目录,把libclFFT.dll复制到exe目录下
clFFT的使用,按照官网的例子即可实现最简单的FFT变换。但要想实现高效的计算,就需要使用clFFT的扩展功能。我只使用1D-FFT,所以尝试了批处理(batch)和转置两种特性。
批处理:(单精度浮点复数,RIRI结构)
err = clfftSetPlanDistance(planHandle,FFT_LEN, FFT_LEN); //分别设置输入、输出数组间距
err = clfftSetPlanBatchSize(planHandle, H_LEN); //设置批处理次数
注意数组间距要填写复数的个数,不是float的个数。
计算的同时转置:(处理不同行序的数据)
需要做非原位的操作,才能实现转置。
size_t outlen[1] = {H_LEN};
err = clfftSetResultLocation(plan_inout, CLFFT_OUTOFPLACE);
err = clfftSetPlanDistance(plan_inout,FFT_LEN,1); //设置数组间距
err = clfftSetPlanOutStride(plan_inout,CLFFT_1D, outlen); //设置输出元素间距
err = clfftSetPlanLength(plan_inout,CLFFT_1D,clLengths); //设置处理长度
err = clfftSetPlanBatchSize(plan_inout,H_LEN); //设置批处理次数
原理是:
输入序列的间距取FFT_LEN,输出序列间距为1个元素;
输出元素间距为原矩阵高(输出矩阵的宽),让输出的下一个元素间隔一行放置
设置处理长度为原矩阵的宽,就是FFT的长度
设置批处理次数,为原矩阵的高,每一行处理一次。
直接转置,会导致时间增加100~200ms/GB
性能对比:
平台 |
运算能力 |
64K点float复数FFT*2048次正变换+反变换 共1GB数据 |
第一台i9-12900H 2.50 GHz单核 |
约0.08T |
9580ms |
第一台Iris Xe核显 |
2T |
传输260ms 处理306ms |
RTX 3070 ti |
21.75T | 传输120ms 处理63ms |
第二台i9-12900H 2.50 GHz单核 |
约0.08T | 10651ms |
RTX 3060 |
12.7T | 传输144ms
处理90ms |