这个问题的答案存储在 vDSP 库中,它是 macOS SDK 的一部分。
https://developer.apple.com/documentation/accelerate/vdsp
vDSP - 对大向量执行基本的算术运算和常见的数字信号处理例程。
在我的情况下,我没有真正的大向量,但仍然如此。
首先,您需要转换unsigned char *
为float *
,顺便说一句,这是一个重要的时刻,我不知道如何在循环中执行此操作。然后你需要两个 vDSP 函数:vDSP_vsbsbm
和vDSP_sve
.
vDSP_vsbsm - 将两个单精度向量的差乘以两个单精度向量的第二个差。
vDSP_sve - 计算单精度向量中的值的总和。
所以最终的代码是这样的:
float *fpxlsA = (float *)malloc(imgA.height * imgA.width * sizeof(float));
float *fpxlsB = (float *)malloc(imgB.height * imgB.width * sizeof(float));
float *output = (float *)malloc(imgB.height * imgB.width * sizeof(float));
for (size_t i = 0; i < imgA.height * imgA.width; ++i) {
fpxlsA[i] = (float)(pxlsA[i]);
fpxlsB[i] = (float)(pxlsB[i]);
}
vDSP_vsbsbm(fpxlsA, 1, fpxlsB, 1, fpxlsA, 1, fpxlsB, 1, output, 1, imgA.height * imgB.width);
float sum;
vDSP_sve(output, 1, &sum, imgA.height * imgB.width);
free(output);
free(fpxlsA);
free(fpxlsB);
因此,这段代码完全符合我的要求,并且采用了更加矢量化的形式。但结果还不够好。比较循环方法和 vDSP 方法的性能,如果没有任何额外的内存分配,vDSP 的速度要快两倍。但实际上,在发生额外内存分配的情况下,循环方法稍微快一些。