c – vector :: operator []开销

c – vector :: operator []开销,第1张

概述显然,在剖析我的(科学计算)C代码之后,25%(!)的时间花在与vector :: operator []的调用上.诚然,我的代码花费了所有的时间读取和写入矢量< float> s(和一些向量< int> s),但是我仍然想知道是否应该有一些显着的 *** 作开销[ ]与C风格的阵列相比? (我已经看到关于SO的另一个相关问题,但是关于[] vs at() – 但显然甚至[]对我来说太慢了! 谢谢, 安东 显然,在剖析我的(科学计算)C代码之后,25%(!)的时间花在与vector :: operator []的调用上.诚然,我的代码花费了所有的时间读取和写入矢量< float> s(和一些向量< int> s),但是我仍然想知道是否应该有一些显着的 *** 作开销[ ]与C风格的阵列相比?

(我已经看到关于SO的另一个相关问题,但是关于[] vs at() – 但显然甚至[]对我来说太慢了!

谢谢,
安东尼

(编辑:只是为了信息:在Ubuntu上使用g -O3版本4.5.2)

解决方法 std :: vector :: operator []应该是相当有效的,但是编译器必须是偏执的,对于对函数的每个调用,它必须假定向量可能已经被移动到内存中的其他位置.

例如在这段代码中

for (int i=0,n=v.size(); i<n; i++){    total += v[i] + foo();}

如果foo的代码不是预先知道的,那么编译器每次都被迫重新加载向量开始的地址,因为向量可能是由于foo()中的代码而被重新分配的.

如果您确定该矢量不会被内存移动或重新分配,那么您可以使用类似于

double *vptr = &v[0]; // Address of first elementfor (int i=0,n=v.size(); i<n; i++){    total += vptr[i] + foo();}

使用这种方法,可以保存一个存储器查找 *** 作(vptr可能最终在整个循环的寄存器中).

低效率的另一个原因可能是缓存垃圾.为了看看这是否是一个问题,一个简单的伎俩是通过一些不均匀的元素来过度分配你的矢量.

原因是因为缓存如何工作,如果你有很多向量,例如4096个元素都将在地址中具有相同的低阶位,并且由于缓存行无效,您可能会最终失去很多速度.
例如我的电脑上的这个循环

std::vector<double> v1(n),v2(n),v3(n),v4(n),v5(n);for (int i=0; i<1000000; i++)    for (int j=0; j<1000; j++)    {        v1[j] = v2[j] + v3[j];        v2[j] = v3[j] + v4[j];        v3[j] = v4[j] + v5[j];        v4[j] = v5[j] + v1[j];        v5[j] = v1[j] + v2[j];    }

如果n == 8191执行约8.1秒,如果n == 10000则在3.2秒内执行.注意,内循环始终为0到999,与n的值无关;只是内存地址有什么不同?

根据处理器/架构的不同,由于缓存丢失,我甚至观察到10倍的速度下降.

总结

以上是内存溢出为你收集整理的c – vector :: operator []开销全部内容,希望文章能够帮你解决c – vector :: operator []开销所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1251052.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-07
下一篇2022-06-07

发表评论

登录后才能评论

评论列表(0条)

    保存