很遗憾,你链接的文章以及这里的某些答案和评论中有一些非常不准确的信息。
让我们从文章开始。磁盘缓存不会对这些函数的性能产生任何影响。虚拟内存被分页到磁盘上是真的,当物理内存需求超过可用内存时,但这不是你必须考虑的因素,当程序使用1.6MB的内存(4*4*100K)。
如果 paging 开始发挥作用,性能差异也不会很微妙。如果这些数组被分页到磁盘并返回,则最快的磁盘性能差异将达到1000倍,而不是10%或100%。
分页和页面故障及其对性能的影响既不是微不足道的,也不是直观的。您需要阅读相关文献,并认真进行实验。那篇文章提供的信息很少,完全不准确,甚至可能误导。
第二个是您的分析策略和微基准测试本身。显然,对于这些数据(一个加法操作)的简单操作,瓶颈将是内存带宽本身(使用这样一个简单的循环可能会有指令 retire 限制之类的问题)。由于您只线性读取内存,并使用所有读取的内容,无论是4个交错流还是2个交错流,您都利用了所有可用的带宽。
但是,如果您在循环中调用function1
或function2
,则将根据 N 测量不同部分的内存层次结构的带宽,从 L1 到 L3 和主内存(您应该知道机器上所有缓存级别的大小和它们的工作原理)。如果您知道 CPU 缓存的工作原理,则这是显而易见的,否则就会产生困惑。您想知道第一次做这件事时速度有多快,当数组尚未被访问时,或者您想测量热访问?
你的真正用例是一遍又一遍地复制相同的中型数组吗?
如果不是,那是什么?你在进行基准测试吗?你试图测量某些东西,还是只是在做实验?
你确定你正在使用正确的编译器开关吗?你看过生成的汇编代码,以确保编译器不会添加调试检查等,并且不会优化掉不应该优化掉的东西(毕竟,你只是执行无用循环,而优化编译器最不想做的就是避免生成不需要的代码)。
你是否查看过硬件的理论内存/缓存带宽数字? 你具体的CPU和RAM组合都有理论限制。无论是5、50还是500 GiB/s,都将为你提供一个上限,告诉你可以移动多少数据并处理。这同样适用于执行单元数量、CPU的IPC以及其他几十个数字,这些数字会影响此类微基准测试的性能。There won't be no disk caching
应该改为 There wouldn't be any disk caching
。(我本可以自己编辑,但需要至少更改10个字符。) - Elliottperf
工具),这可以极大地帮助你。 - yzt我在这里插一句话,提醒大家在关注性能时要记住一些事情 - 除非你正在编写实时设备的嵌入式软件,否则此类低级代码的性能不应成为问题。
在99.9%的其他情况下,它们将足够快。