因为高斯卷积核计算具有可分离的性质,其计算过程的复杂度比不可分离的卷积要高,因此直接对比自己实现的3D高斯卷积与高性能库IPP的执行情况是没意义的。但是,只进行一维卷积,对比两个版本是有参考价值的。本篇通过Intel高性能计算库IPP中的卷积计算API实现一维卷积,并记录程序耗时情况,同时与 C++性能优化系列——3D高斯核卷积计算(二)FMA向量化计算一维卷积 中只通过编译器向量化版本对比性能。
功能实现
程序逻辑:ippsConvolve_32f实现卷积需要获取一块额外的内存,因此整个流程大致为:计算内存尺寸,申请内存,调用卷积API,释放内存。为了对比公平,只将卷积计算部分重复CONVREPEAT次。
代码实现:
void Conv1d_IPP(float* pSrc, int iLength, float* pKernel, int kernelSize, float* pDst)
{
IppEnum funCfg = (IppEnum)(ippAlgAuto);
int bufSize = 0;
Ipp8u *pBuffer;
IppStatus status = ippsConvolveGetBufferSize(iLength, kernelSize, ipp32f, funCfg, &bufSize);
pBuffer = ippsMalloc_8u(bufSize);
for (int i = 0; i < CONVREPEAT; ++i)
{
status = ippsConvolve_32f(pSrc, iLength, pKernel, kernelSize, pDst, funCfg, pBuffer);
}
ippsFree(pBuffer);
}
耗时情况:
TestConv1D(Conv1d_IPP) cost total Time 65 ms
TestConv1D cost Time 0.00065
仅通过编译器向量化的程序执行时间是60 ms,IPP一维卷积的耗时略多。
API解释
解释来自IPP Developer Reference,这里将文档中关于用到函数的解释列出,不再详细说明。
ippsConvolveGetBufferSize
ippsConvolve_32f
VTune分析性能瓶颈
由于IPP闭源,这里无法看到函数内部具体的执行情况,只能看到ipps库的整体性能瓶颈。
整个库函数执行了8.8亿次指令与对比版本相当,CPI与对比版本(0.31)略高。因此执行时间与对比版本慢了一些。
因为IPP是夸平台的通用函数库,为了兼容不同平台的CPU特性,一些向量化的实现无法与ICC编译器针对特定平台的向量化优化相比,以牺牲性能换来跨平台的优势。
总结
本篇提供了通过IPP进行一维卷积计算的代码程序,并通过VTune分析执行情况。与C++性能优化系列——3D高斯核卷积计算(二)FMA向量化计算一维卷积 中实现的版本对比,IPP速度略慢。