【发布时间】:2023-03-28 17:58:01
【问题描述】:
我的问题是关于访问双 std::array 元素的效率。由于std::array 是一个静态大小的容器,我希望它的数据存储在一个连续的内存块中,并且访问std::array 的元素与C 样式数组相同。使用std::array 不应增加任何额外开销。
访问双精度数组std::array<std::array<T,N>,M> 的元素是否已优化?
例如我必须在下面提供源代码。
#include <array>
#include <random>
int main(){
std::array<std::array<int,4>,2> a;
for(int j=0;j<4;j++)
a[0][j] = rand();
for(int j=0;j<4;j++)
a[1][j] = rand();
int r = a[0][1] + a[1][3];
return r;
}
-
a是否使用单个内存块? - 访问具有常量索引的元素(即
a[1][3])是内存中的单次移位还是双次移位? - 在循环中访问元素需要多少次移位(即
a[1][j])
我在上面的例子中使用了 godbolt.org 来检查汇编代码,看起来gcc -O4做得很好。
例如访问a[1][3]和a[0][1]被编译为:
mov eax, DWORD PTR [rsp+28]
add eax, DWORD PTR [rsp+4]
但是,我可以在更复杂的示例中使用此发现吗?
还是我应该坚持简单的std::arrays来控制访问效率?
双std::array中是否有任何ISO标准描述?
【问题讨论】:
-
你所说的“记忆转移”是什么意思?您确定您没有进行通常很糟糕的过早优化吗?您是否测量(或分析或基准测试)这是您程序中的瓶颈?首先要专注于编写编写良好、可读性强、易于理解、可维护和工作的代码。 那么如果“性能”不符合您衡量和分析的现有要求,以找到热点和瓶颈,并将您的优化工作集中在重要的地方,并提供大量文档和了解你在做什么。
-
使用
std::vector除非您需要std::array用于某些明确的目的。并在考虑优化之前进行测量。查看为具有分支预测、乱序执行、推测执行等的现代 CPU 生成的代码几乎毫无意义,除非您已经具备非常专业的知识。 -
没有
-O4。但是std::arrays 是一个连续的块。 -
@Someprogrammerdude 使用术语“内存转移”我试图总结我们在
std::vector<std::vector<T>>中所做的双重查找。我的问题不是关于优化我的来源。这是关于std::array的定义和描述。