C++性能优化系列——3D高斯核卷积计算(十二)Intrinsic实现

it2023-02-18  77

void GaussSmoothCPU3DOptZYXSplitZIntrinsic(float* pSrc, int iDim[3], float* pKernel, int kernelSize[3], float* pDst, float* pBuffer) { //计算结果正确 //16 thread dynamic GaussSmoothCPU3DOptZYXSplitZIntrinsic cost Time(ms) 145.8 int iSliceSize = iDim[1] * iDim[0]; int nCenter = kernelSize[0] / 2; const unsigned int InnerSize = 16*2; #pragma omp parallel for num_threads(16) schedule(dynamic) for (int z = 0; z < (iDim[2] - kernelSize[0] + 1); z++) { float* pBuffSlice = pBuffer + (z + nCenter) * iSliceSize; float* pDstSlice = pDst + (z + nCenter) * iSliceSize; { for (unsigned int iSliceIt = 0; iSliceIt < iSliceSize; iSliceIt += InnerSize) { float* pSrcSlice = pSrc + z * iSliceSize + iSliceIt; __m256 DST1 = _mm256_setzero_ps(); __m256 DST2 = _mm256_setzero_ps(); __m256 DST3 = _mm256_setzero_ps(); __m256 DST4 = _mm256_setzero_ps(); for (unsigned int kx = 0; kx < kernelSize[0]; kx++) { __m256 SRC1 = _mm256_loadu_ps(pSrcSlice + kx * iSliceSize); __m256 SRC2 = _mm256_loadu_ps(pSrcSlice + kx * iSliceSize + 8); __m256 SRC3 = _mm256_loadu_ps(pSrcSlice + kx * iSliceSize + 16); __m256 SRC4 = _mm256_loadu_ps(pSrcSlice + kx * iSliceSize + 24); __m256 KER = _mm256_broadcast_ss(pKernel + kx); DST1 = _mm256_fmadd_ps(KER, SRC1, DST1); DST2 = _mm256_fmadd_ps(KER, SRC2, DST2); DST3 = _mm256_fmadd_ps(KER, SRC3, DST3); DST4 = _mm256_fmadd_ps(KER, SRC4, DST4); } _mm256_store_ps(pBuffSlice + iSliceIt, DST1); _mm256_store_ps(pBuffSlice + iSliceIt + 8, DST2); _mm256_store_ps(pBuffSlice + iSliceIt + 16, DST3); _mm256_store_ps(pBuffSlice + iSliceIt + 24, DST4); } } int tid = omp_get_thread_num(); memset(yBuf[tid], 0, sizeof(float) * iDim[0] * iDim[1]); Conv2D_Fuse(pBuffSlice, iDim, pKernel, kernelSize[0], yBuf[tid], pDstSlice, NULL); } }

最新回复(0)