优化C中的向量/矩阵运算?

时间:2014-09-03 18:33:14

标签: c math memory optimization

我试图看看我是否可以将C中的数学向量(和/或矩阵)运算优化为项目。我注意到,例如,memcpy比循环快得多,因为它使用低级硬件辅助内存操作,但我并不熟悉它的工作原理。

是否有可能做类似的事情,但是对于诸如将两个浮点数组相加或相乘(而不仅仅是复制)这样的操作?

2 个答案:

答案 0 :(得分:1)

我从你的个人资料中看到你正在处理opengl,我写了下面的答案,假设你想要处理线性代数。在你的情况下,除此之外别无他法;

  • 循环展开
  • 防止间接索引
  • 定位内存缓存
  • 编译器/链接器优化

你处在一个巨大的研究领域。您可以使用“计算线性代数”,“矩阵存储方案”,“矩阵向量运算”等在文献中搜索数百万种出版物。

可能有数千个库,工具和实用程序试图优化这些计算 然而,一组低级库BLAS被接受为标准密集矩阵库。很多密集和稀疏的vec-vec,mat-vec,mat-mat功能建立在它上面。可以使用单处理器或多处理器工具(并发和分布式)甚至已经存在GPU支持的解决方案。

Jack Dongarra是这一主题的主要研究人员之一。我相信您可以通过使用上面给出的关键字找到很多来源。

AFAIK,没有像memcpy这样的优化,因为它是内置功能。如果文献中存在类似的内容,则可以在BLAS中找到。

BLAS通过编译器/链接器为特定的操作系统和硬件提供了几个优化。(如循环展开,缓存等)。

答案 1 :(得分:1)

首选方法涉及使用某人已经开发的库,并花一些时间进行调整以获得更好的性能。

但是,如果您对自己这样做感兴趣,最简单的优化之一就是增加指针,而不是使用偏移数学(Semih Ozmen在下面将其称为间接寻址)。例如,考虑添加长度为a的两个向量bN,并将结果放在长度为c的第三个向量N中。天真的方法是:

for (unsigned int i = 0; i < N; ++i) {
    c[i] = a[i] + b[i];
}

这里必须将每个数组元素的存储位置计算为基本存储器地址加上基于目标数组元素的索引和数组数据元素大小的偏移量。另一种方法是使用指针,如:

double *ap = a, *bp = b, *cp = c;
for (unsigned int i = 0; i<N; ++i, ++ap, ++bp, ++cp) {
    *cp = *ap + *bp;
}

在这种情况下,消除了基于与基地址的偏移来计算数组元素地址。这种通用方法可用于许多向量和矩阵运算中的任何一种,包括加法和乘法。

FWIW,C ++迭代器,如果正确实现,通常会使用这样的方法,同时隐藏实现细节,以使程序员更安全。