我正在运行蒙特-卡罗实验,并评估下面描述的绝对损失函数。由于它是非常计算密集型的,我想优化我的代码,并进一步提高速度。我的主要代码是在MATLAB中,但我使用MATLAB的MEX功能在C中计算函数。
数学问题如下:我有一个维数为(M乘N)的矩阵D。通常,M约为20,000,N取值约为{10,30,144}。
Definition of matrix D
实际上,我需要获得L列向量,其维度(M乘以1)定义为
Definition of matrix L
我的C函数看起来像这样:
void absolute_loss(double *D, double *L, mwSize cols, mwSize rows)
{
double aux;
int i;
int j;
int k;
for (i = 0; i < rows; i++) {
for (j = 0; j < rows; j++){
aux = 0;
for (k = 0; k < cols; k++) {
aux = aux + fabs(D[j + rows * k] - D[i + rows * k]);
}
L[i] = L[i] + aux;
}
}
for (i = 0; i < rows; i++) {
L[i] /= rows;
}
}
任何建议都非常感谢。
2条答案
按热度按时间ru9i0ody1#
如何加快绝对损失矩阵的计算速度
float
类型和float
函数。有时候快4倍。对我来说,快了8%。restrict
让编译器知道引用的数据没有重叠。否则,编译器必须假设L[i] = ...;
可能会更改D[]
,这将阻止某些优化。const
。size_t
和unsigned
差不多。unsigned short
速度快5%。注意事项:
我希望在函数的开始出现以下内容。
提示,而不是
rows, cols, i, j
,使用M, N, m, n
来匹配公式。我不确定你是否正确。利用variable length arrays和示例用法的候选重写:
我的时间:4.906秒。
8aqjt8rx2#
你的矩阵D的行和列似乎有一个不寻常的排列。您的函数使用索引访问数据,这些索引会跳来跳去,无法充分利用内存缓存。重新排列循环可以使它处理大部分连续的元素,从而显著提高性能。在我的电脑上,这个运行速度几乎是你发布的M=10000,N=30的函数的3倍。
您可能会以牺牲简单性为代价,用SIMD构建一个更快的函数,特别是如果您想保持可移植性的话。不过,这不是一个微不足道的重构。