Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 处理连续内存块与非连续内存块时的效率_C++ - Fatal编程技术网

C++ 处理连续内存块与非连续内存块时的效率

C++ 处理连续内存块与非连续内存块时的效率,c++,C++,我有一个结构 struct A { int v[10000000]; }; 如果我有A[2]并希望计算这两种方法中哪一种最快的值的总和 int method_1(const A &a[],int length) { int total = 0; for(int i=0;i<length;i++) for(int j=0;j<10000000;j++) total+=a[i][j]; return total; } int method_2(const A &a

我有一个结构

struct A
{
int v[10000000];
};
如果我有
A[2]
并希望计算这两种方法中哪一种最快的值的总和

int method_1(const A &a[],int length)
{
int total = 0;
for(int i=0;i<length;i++)
for(int j=0;j<10000000;j++)
total+=a[i][j];

return total;
}


int method_2(const A &a[],int length)
{
int total = 0;
for(int j=0;j<10000000;j++)
for(int i=0;i<length;i++)
total+=a[i][j];

return total;
}
int方法_1(常数A&A[],int长度)
{
int-total=0;

对于(int i=0;i数据大小足够小,可以完全放在现代CPU上的单个缓存线中。我不确定是否通过编译器将此代码垂直化。我不认为方法_2比方法_1慢。内存块将被带到CPU主内存,然后访问[0]和[1]将花费相同的时间


为了安全起见,方法_1通常被认为比方法_2更好。

在大多数情况下,按元素在内存中出现的顺序访问元素会提高性能,因为它允许预取器在您使用数据之前加载数据。此外,如果您以非连续方式使用数据,您可能会多次加载并丢弃同一缓存线这是有成本的。

每次读取内存片段时,整个缓存线都会从主存读取到CPU缓存,今天可能会有32字节长的缓存线。主要是因为读取连续内存块的速度很快

现在有多个缓存线

在您的情况下,这两种情况可能具有相似的性能,因为两个阵列很可能不会碰撞到同一缓存线,因此两者可能位于不同缓存线上,因此我怀疑性能会相似

在这种情况下,你可以考虑改变性能的一个相关的事情不是使用[]操作符,而是喜欢重复使用这样的迭代器:

int method_1(const A &a[],int length)
{
    int total = 0;
    for(const A* aIt=a;aIt<a+length;++aIt)
        for(const v* vIt=aIt->v;vIt<aIt->v+10000000;++vIt)
            total+=*vIt;

    return total;
}
int方法_1(常数A&A[],int长度)
{
int-total=0;
对于(常数A*aIt=A;aItv;vItv+10000000;+vIt)
总+=*vIt;
返回总数;
}

这样就避免了double[]的出现,double[]是数组元素的sizeof的简单乘法(可能会优化,但可能不会优化,如果没有优化,则在调用数百万次时成本会很高)。您的编译器可能足够聪明,可以优化代码,正如我所展示的那样,只使用加法,但是……它可能不是很好,而且我已经看到,当为每个元素执行的操作都像增量一样微不足道时,这会产生很大的差异-您最好对此进行测量,并看看这些选项在您的环境中是如何工作的。

Benchmark!调用每个函数一百万次,并对循环计时。有优化和没有优化。你也可以查看生成的代码,看看是否有很多差异。
方法1
更直观,更容易阅读/理解。我会坚持这一点……对于这些小事情,我认为任何真正的差异都是统计的虽然不重要,但这只是一个猜测……按照@JoachimPileborg所说的去做……除了代码不可编译(缺少类型)之外JoaPixiBrg不能简单地把工作放在纯的基准测试上。对于简单的情况,这是很容易的,但是对于复杂的情况,它更难。我可能感兴趣的是,在那里,可能有可能使用的预加载程序,或者其他的C++,在数据包中,P是数据。为了解释的目的。v可以容纳百万,而“a”的长度可能有几千。@BadescuAlexandru:但是你有这个想法,不是吗?对于更大的数据来说,CPU缓存对性能非常重要。我对编译器的缓存处理有点不熟悉。据我所知,当读取内存片段时,它们存储在s中ets和线路,但在任何给定时间只有一组处于活动状态。如何确定线路编号,以及线路实际包含的内容(即从“何处”到“何处”)为什么集合会滑入行中?@BadescuAlexandru编译器不处理缓存。但是它知道缓存是如何工作的,并尽可能优化代码,使其对缓存友好。对于集合和行的内容,您可能需要阅读。