Assembly 指令计数类型为什么有这么多数据操作?
我有一个程序,它基本上是循环的,在每个循环中进行大量的加法运算 所以像b+=.01在一个循环中可能发生了100次 因此,我预计计算(添加)与加载和存储指令的比率将非常高。然而,出乎意料的是,我添加的内容越多,读取和写入的内存就越多Assembly 指令计数类型为什么有这么多数据操作?,assembly,opcode,Assembly,Opcode,我有一个程序,它基本上是循环的,在每个循环中进行大量的加法运算 所以像b+=.01在一个循环中可能发生了100次 因此,我预计计算(添加)与加载和存储指令的比率将非常高。然而,出乎意料的是,我添加的内容越多,读取和写入的内存就越多 int b = 0; int i; for (i = 0; i < 100000; i++){ b += .01 * (maybe 50 times)?) } intb=0; int i; 对于(i=0;i
int b = 0;
int i;
for (i = 0; i < 100000; i++){
b += .01 * (maybe 50 times)?)
}
intb=0;
int i;
对于(i=0;i<100000;i++){
b+=.01*(可能是50倍)?)
}
我用的是pin工具,内存读写量增加了很多。比添加快得多。我很困惑。我认为b是一个局部变量,因此,它不是存储在内存中,而是存储在堆栈或缓存中。为什么会发生这种情况
我查看了程序集,发现lw或sw在任何地方都没有使用。默认情况下,编译器几乎总是在堆栈上放置具有自动生存期的变量(例如
int b=0;
)
例如,如果我使用GCC编译此代码段,它与您编写的代码接近,但更正确一点:
intmain()
{
int b=0;
int i;
对于(i=0;i<100000;i++){
b++;
b++;
b++;
b++;
b++;
b++;
b++;
b++;
b++;
b++;
}
返回b;
}
我得到以下编译代码:
00000000004004b6 <main>:
4004b6: 55 push %rbp
4004b7: 48 89 e5 mov %rsp,%rbp
4004ba: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
4004c1: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%rbp)
4004c8: eb 2c jmp 4004f6 <main+0x40>
4004ca: 83 45 fc 01 addl $0x1,-0x4(%rbp)
4004ce: 83 45 fc 01 addl $0x1,-0x4(%rbp)
4004d2: 83 45 fc 01 addl $0x1,-0x4(%rbp)
4004d6: 83 45 fc 01 addl $0x1,-0x4(%rbp)
4004da: 83 45 fc 01 addl $0x1,-0x4(%rbp)
4004de: 83 45 fc 01 addl $0x1,-0x4(%rbp)
4004e2: 83 45 fc 01 addl $0x1,-0x4(%rbp)
4004e6: 83 45 fc 01 addl $0x1,-0x4(%rbp)
4004ea: 83 45 fc 01 addl $0x1,-0x4(%rbp)
4004ee: 83 45 fc 01 addl $0x1,-0x4(%rbp)
4004f2: 83 45 f8 01 addl $0x1,-0x8(%rbp)
4004f6: 81 7d f8 9f 86 01 00 cmpl $0x1869f,-0x8(%rbp)
4004fd: 7e cb jle 4004ca <main+0x14>
4004ff: 8b 45 fc mov -0x4(%rbp),%eax
400502: 5d pop %rbp
400503: c3 retq
400504: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
40050b: 00 00 00
40050e: 66 90 xchg %ax,%ax
00000000004004b6 <main>:
4004b6: 55 push %rbp
4004b7: 48 89 e5 mov %rsp,%rbp
4004ba: 53 push %rbx
4004bb: bb 00 00 00 00 mov $0x0,%ebx
4004c0: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%rbp)
4004c7: eb 22 jmp 4004eb <main+0x35>
4004c9: 83 c3 01 add $0x1,%ebx
4004cc: 83 c3 01 add $0x1,%ebx
4004cf: 83 c3 01 add $0x1,%ebx
4004d2: 83 c3 01 add $0x1,%ebx
4004d5: 83 c3 01 add $0x1,%ebx
4004d8: 83 c3 01 add $0x1,%ebx
4004db: 83 c3 01 add $0x1,%ebx
4004de: 83 c3 01 add $0x1,%ebx
4004e1: 83 c3 01 add $0x1,%ebx
4004e4: 83 c3 01 add $0x1,%ebx
4004e7: 83 45 f4 01 addl $0x1,-0xc(%rbp)
4004eb: 81 7d f4 9f 86 01 00 cmpl $0x1869f,-0xc(%rbp)
4004f2: 7e d5 jle 4004c9 <main+0x13>
4004f4: 89 d8 mov %ebx,%eax
4004f6: 5b pop %rbx
4004f7: 5d pop %rbp
4004f8: c3 retq
4004f9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
您将获得以下编译代码:
00000000004004b6 <main>:
4004b6: 55 push %rbp
4004b7: 48 89 e5 mov %rsp,%rbp
4004ba: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
4004c1: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%rbp)
4004c8: eb 2c jmp 4004f6 <main+0x40>
4004ca: 83 45 fc 01 addl $0x1,-0x4(%rbp)
4004ce: 83 45 fc 01 addl $0x1,-0x4(%rbp)
4004d2: 83 45 fc 01 addl $0x1,-0x4(%rbp)
4004d6: 83 45 fc 01 addl $0x1,-0x4(%rbp)
4004da: 83 45 fc 01 addl $0x1,-0x4(%rbp)
4004de: 83 45 fc 01 addl $0x1,-0x4(%rbp)
4004e2: 83 45 fc 01 addl $0x1,-0x4(%rbp)
4004e6: 83 45 fc 01 addl $0x1,-0x4(%rbp)
4004ea: 83 45 fc 01 addl $0x1,-0x4(%rbp)
4004ee: 83 45 fc 01 addl $0x1,-0x4(%rbp)
4004f2: 83 45 f8 01 addl $0x1,-0x8(%rbp)
4004f6: 81 7d f8 9f 86 01 00 cmpl $0x1869f,-0x8(%rbp)
4004fd: 7e cb jle 4004ca <main+0x14>
4004ff: 8b 45 fc mov -0x4(%rbp),%eax
400502: 5d pop %rbp
400503: c3 retq
400504: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
40050b: 00 00 00
40050e: 66 90 xchg %ax,%ax
00000000004004b6 <main>:
4004b6: 55 push %rbp
4004b7: 48 89 e5 mov %rsp,%rbp
4004ba: 53 push %rbx
4004bb: bb 00 00 00 00 mov $0x0,%ebx
4004c0: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%rbp)
4004c7: eb 22 jmp 4004eb <main+0x35>
4004c9: 83 c3 01 add $0x1,%ebx
4004cc: 83 c3 01 add $0x1,%ebx
4004cf: 83 c3 01 add $0x1,%ebx
4004d2: 83 c3 01 add $0x1,%ebx
4004d5: 83 c3 01 add $0x1,%ebx
4004d8: 83 c3 01 add $0x1,%ebx
4004db: 83 c3 01 add $0x1,%ebx
4004de: 83 c3 01 add $0x1,%ebx
4004e1: 83 c3 01 add $0x1,%ebx
4004e4: 83 c3 01 add $0x1,%ebx
4004e7: 83 45 f4 01 addl $0x1,-0xc(%rbp)
4004eb: 81 7d f4 9f 86 01 00 cmpl $0x1869f,-0xc(%rbp)
4004f2: 7e d5 jle 4004c9 <main+0x13>
4004f4: 89 d8 mov %ebx,%eax
4004f6: 5b pop %rbx
4004f7: 5d pop %rbp
4004f8: c3 retq
4004f9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
0000000000 4004B6:
4004b6:55推送%rbp
4004b7:48 89 e5 mov%rsp,%rbp
4004ba:53推送%rbx
4004bb:bb 00 mov$0x0,%ebx
4004c0:c7 45 f4 00移动值$0x0,-0xc(%rbp)
4004c7:eb 22 jmp 4004eb
4004c9:83 c3 01添加$0x1,%ebx
4004cc:83 c3 01添加$0x1,%ebx
4004cf:83 c3 01添加$0x1,%ebx
4004d2:83 c3 01添加$0x1,%ebx
4004d5:83 c3 01添加$0x1,%ebx
4004d8:83 c3 01添加$0x1,%ebx
4004db:83 c3 01添加$0x1,%ebx
4004de:83 c3 01添加$0x1,%ebx
4004e1:83 c3 01添加$0x1,%ebx
4004e4:83 c3 01添加$0x1,%ebx
4004e7:83 45 f4 01地址$0x1,-0xc(%rbp)
4004eb:81 7d f4 9f 86 01 00 cmpl$0x1869f,-0xc(%rbp)
4004f2:7e d5 jle 4004c9
4004f4:89 d8 mov%ebx,%eax
4004f6:5b流行音乐%rbx
4004f7:5d pop%rbp
4004f8:c3 retq
4004f9:0f 1f 80 00 nopl 0x0(%rax)
请注意,递增的指令现在是添加$0x1,%ebx,我们可以看到变量确实按照请求存储在寄存器中(此处为ebx
)
我认为b是一个局部变量,因此,它不是存储在内存中,而是存储在堆栈或缓存中。为什么会发生这种情况
局部变量通常存储在内存中(在堆栈上)。但是你可以改变这种行为。在我发布的第二个代码片段中,您将看到更少的内存读/写操作,因为
b
不再存储在主内存中,而是存储在寄存器中。“只是堆栈”,而不是内存中?您的计算机中是否有一个不需要内存的神奇“堆栈附加组件”?请尝试将b
更改为double
。