在讨论地方性原则时,我的教科书做了如下陈述:
除分支和通话指令外,它们只构成一个小的 所有程序指令的一部分,程序执行是顺序的。 因此,在大多数情况下,要立即获取指令 跟随最后一条指令。
作为一个新手,我觉得这很难相信。我遇到的所有代码都充满了调用指令。实际上,在我看来,呼叫指令实际上是在程序中执行最重要的操作。
如果有人能详细说明为什么这个概念是真的,我会非常感激,尽管呼叫指令在程序中扮演了重要的角色。
答案 0 :(得分:0)
我在计算机上选择了一个随机二进制文件cargo
包管理器。然后我:
otool -tvV cargo > assembly
cat assembly | awk '{print $2}' > instructions
sort instructions | uniq -c | sort -n > count
我将Libreoffice Calc中的结果处理成每个指令的出现列表。以下是每个程序中超过1%的程序(这些总计达到86%,因此我为了酿造而丢弃了大量的流浪操作):
| 34.83% | movq |
| 7.30% | leaq |
| 7.00% | callq |
| 6.90% | je |
| 5.61% | movl |
| 4.86% | cmpq |
| 3.77% | testq |
| 3.11% | jmp |
| 2.23% | jne |
| 2.17% | popq |
| 2.05% | pushq |
| 1.69% | addq |
| 1.29% | cmpl |
| 1.20% | movabsq |
| 1.18% | movb |
| 1.05% | xorl |
这里肯定有很多分支和调用(callq
,jmp
,je
,jne
),但也有很多内存操作。内存操作相对较慢,构成了程序的大部分运行时间。 movq
只是一个内存操作,它占该程序的三分之一以上!
CPU缓存用于将最近引用的内存数据保持在CPU内核附近,从而加快了对相同数据的未来内存操作。他们可以这样做,因为Principle of Locality表明同一记忆中的操作经常接近时间(时间局部性)。因此,可以缓存内存数据,因为您可能很快就会需要它。