我们认为内存访问是快速且持续的,但在现代架构/操作系统上,这不一定是真的。
考虑以下C代码:
int i = 34;
int *p = &i;
// do something that may or may not involve i and p
{...}
// 3 days later:
*p = 643;
如果
,CPU指令中最后一次分配的估计成本是多少i
位于L1缓存中,i
位于二级缓存中,i
位于L3缓存中,i
在RAM中,i
被分页到SSD磁盘,i
被分页到传统磁盘? i
还能在哪里?
当然这些数字并不是绝对的,但我只对数量级感兴趣。我试着在网上搜索,但谷歌这次没有给我保佑。
答案 0 :(得分:13)
这里有一些硬数字,证明精确时间因CPU系列和版本而异:http://www.agner.org/optimize/
这些数字是一个很好的指南:
L1 1 ns
L2 5 ns
RAM 83 ns
Disk 13700000 ns
并且作为给你数量级的infograph:
答案 1 :(得分:3)
Norvig从2001年开始有一些values。从那时起事情发生了一些变化,但我认为相对速度仍大致正确。
答案 2 :(得分:1)
它也可能在CPU寄存器中。 C / C ++ - 关键字“register”告诉CPU将变量保存在寄存器中,但是你不能保证它会保留甚至永远不会进入寄存器。
答案 3 :(得分:1)
只要Cache / RAM / Harddisk / SSD不忙于提供其他访问(例如DMA请求)并且硬件相当可靠,那么成本仍然是恒定的(尽管它们可能是一个很大的常量)。 / p>
当你得到一个缓存未命中,并且你必须寻呼到硬盘来读取变量时,那它只是一个简单的硬盘读取请求,这个成本是巨大的,因为CPU必须:向内核发送中断以进行硬盘读取请求,向硬盘发送请求,等待硬盘将数据写入RAM,然后从RAM读取数据到缓存和寄存器。但是,这笔费用仍然是不变的。
实际数量和比例将根据您的硬件和硬件的兼容性而有所不同(例如,如果您的CPU运行速度为2000 Mhz,而您的RAM以333 Mhz发送数据,那么它们的同步性就不会很好)。你可以解决这个问题的唯一方法是在你的程序中测试它。
这不是过早优化,这是微优化。让编译器担心这些细节。
答案 4 :(得分:1)
这些数字一直在变化。但是对于2010年的粗略估计Kathryn McKinley has nice slides on the web,我不觉得有必要在这里复制。
您想要的搜索词是“内存层次结构”或“内存层次结构成本”。
答案 5 :(得分:0)
我还能在哪里?
i
和*i
是不同的东西,它们都可以位于列表中的任何位置。在进行分配时,指针地址可能还会存储在CPU寄存器中,因此不需要从RAM / Cache / ...中取出它。
关于性能:这是高度依赖于CPU。按照数量级进行思考,访问RAM比访问缓存条目和访问换出页面更糟糕。所有这些都有点不可预测,因为它们也依赖于其他因素(即其他处理器,具体取决于系统架构)。