如何以优化的方式同时迭代两个间距不相等的数组



假设我必须将两个数组(如A[MAX_BUFFER]B[MAX_BUFFER](与MAX_BUFFER = 256相乘。

由于某种原因,每个B[MAX_BUFFER]值都是以固定的控制速率(例如8(计算的,因为每个值都将被大量处理。

稍后,考虑到(引入的(不同的间距,我需要将彼此相乘到C[MAX_BUFFER]。因此,对于256个值上的A,我将得到一个大小可变的B(在本例中为32,因为控制率为8(。

下面是一个示例代码:

#include <iostream>
#include <math.h>
#define MAX_BUFFER 256
double HeavyFunction(double value) {
if (value == 0) return 0.0;
return pow(10.0, value); // heavy operations on value...
}
int main()
{    
int blockSize = 256;
int controlRate = 8;
double A[MAX_BUFFER];
double B[MAX_BUFFER];
double C[MAX_BUFFER];
// fill A
for (int sampleIndex = 0; sampleIndex < blockSize; sampleIndex++) {
A[sampleIndex] = sampleIndex;
}
// fill B (control rated)
int index = 0;
for (int sampleIndex = 0; sampleIndex < blockSize; sampleIndex += controlRate, index++) {
B[index] = HeavyFunction(index);
}
// calculate C
for (int sampleIndex = 0; sampleIndex < blockSize; sampleIndex++) {     
C[sampleIndex] = A[sampleIndex] + B[sampleIndex / 8];
std::cout << C[sampleIndex] << std::endl;
}
}

我需要性能,因为我将并行处理许多这样的操作,在1秒内发送许多数据(类似于在blockSize<=MAX_BUFFER中分割的44100个样本(。

我希望避免分支(即if(和除法(如上面的例子(,它们不是类似CPU的操作(处理大量数据(。

在前面的例子中,这将引入sampleIndex / 8 * N的"徒劳"N运算;如果我对数百万个样本调用该程序。。。

您将如何为CPU以一种奇特而轻松的方式重构这些代码?

我认为优化器可能单独完成这项工作,但您可以展开循环以避免除法:

// calculate C
const max = blockSize / 8;
int j = 0;
for (int i = 0; i != max; ++i) {
const auto b = B[i];
C[j] = A[j] + b; std::cout << C[j] << std::endl; ++j;
C[j] = A[j] + b; std::cout << C[j] << std::endl; ++j;
C[j] = A[j] + b; std::cout << C[j] << std::endl; ++j;
C[j] = A[j] + b; std::cout << C[j] << std::endl; ++j;
C[j] = A[j] + b; std::cout << C[j] << std::endl; ++j;
C[j] = A[j] + b; std::cout << C[j] << std::endl; ++j;
C[j] = A[j] + b; std::cout << C[j] << std::endl; ++j;
C[j] = A[j] + b; std::cout << C[j] << std::endl; ++j;
}

如何以优化的方式同时迭代两个间距不相等的数组?

简短回答:关注HeavyFunction,避免在线程之间共享不必要的东西。

不幸的是,你的例子不符合这个问题。阵列

double A[MAX_BUFFER];
double B[MAX_BUFFER];
double C[MAX_BUFFER];

只需移动堆栈指针就可以在堆栈上分配,所以可以说它们非常类似于一个连续的数组。

即使它们不是,现代缓存也是如此复杂,以至于通过尝试微观优化,最终可能会降低性能。

假设你有

BUFFER_SIZE = 1024 * 1024 * 1024;
std::vector<double> A(MAX_BUFFER);
std::vector<double> B(MAX_BUFFER);

是一个很好的改进

std::vector<double> C{A};
for (int i = 0; i < blockSize/controlRate; i++) { 
const double b = B[i];
int indexStart = i*controlRate;
for(int j = 0 ; j < controlRate; ++j){
Cprime[indexStart+j] += b;
}
}

你读一次A(以块为单位(,读一次B(一次读两次(,访问C的时间相同。

相关内容

  • 没有找到相关文章

最新更新