[英]c++ bitset not inlined?
我尝试以下方法:
#include <bitset>
int main ()
{
std::bitset<32> bit32 { 0xf0f0f0f0 };
bit32[4].flip();
bit32[0] = 1;
}
使用GCC 4.8.1,我无法将其内联,objdump给了我更多或更少:
401536: c7 45 e4 f0 f0 f0 f0 movl $0xf0f0f0f0,-0x1c(%ebp)
40153d: 8d 45 e8 lea -0x18(%ebp),%eax
401540: c7 44 24 04 04 00 00 movl $0x4,0x4(%esp)
401547: 00
401548: 8d 55 e4 lea -0x1c(%ebp),%edx
40154b: 89 14 24 mov %edx,(%esp)
40154e: 89 c1 mov %eax,%ecx
401550: e8 93 13 00 00 call 4028e8 <__ZNSt6bitsetILj32EEixEj>
401555: 83 ec 08 sub $0x8,%esp
401558: 8d 45 e8 lea -0x18(%ebp),%eax
40155b: 89 c1 mov %eax,%ecx
40155d: e8 b2 12 00 00 call 402814 <__ZNSt6bitsetILj32EE9reference4flipEv>
401562: 8d 45 e8 lea -0x18(%ebp),%eax
401565: 89 c1 mov %eax,%ecx
401567: e8 10 13 00 00 call 40287c <__ZNSt6bitsetILj32EE9referenceD1Ev>
40156c: 8d 45 f0 lea -0x10(%ebp),%eax
40156f: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp)
401576: 00
401577: 8d 55 e4 lea -0x1c(%ebp),%edx
40157a: 89 14 24 mov %edx,(%esp)
40157d: 89 c1 mov %eax,%ecx
40157f: e8 64 13 00 00 call 4028e8 <__ZNSt6bitsetILj32EEixEj>
401584: 83 ec 08 sub $0x8,%esp
401587: 8d 45 f0 lea -0x10(%ebp),%eax
40158a: c7 04 24 01 00 00 00 movl $0x1,(%esp)
401591: 89 c1 mov %eax,%ecx
401593: e8 f0 12 00 00 call 402888 <__ZNSt6bitsetILj32EE9referenceaSEb>
401598: 83 ec 04 sub $0x4,%esp
40159b: 8d 45 f0 lea -0x10(%ebp),%eax
40159e: 89 c1 mov %eax,%ecx
4015a0: e8 d7 12 00 00 call 40287c <__ZNSt6bitsetILj32EE9referenceD1Ev>
4015a5: b8 00 00 00 00 mov $0x0,%eax
4015aa: 8b 4d fc mov -0x4(%ebp),%ecx
-O1,-O2,-O3也不起作用,它完全优化了代码。 无论如何,我可以避免调用函数吗?
在启用优化的情况下进行编译。 当我使用g++ -std=c++11 -O3
和以下稍微修改过的代码进行编译时,它会输出非常优化的代码:
输入:
#include <bitset>
volatile unsigned long v;
int main ()
{
std::bitset<32> bit32 { 0xf0f0f0f0 };
bit32[4].flip();
bit32[0] = 1;
v = bit32.to_ulong();
}
编译器输出:
main:
.LFB958:
.cfi_startproc
movl $4042322145, %eax
movq %rax, v(%rip)
xorl %eax, %eax
ret
.cfi_endproc
我需要添加volatile
变量以防止G ++彻底优化它。 它基本上优化了所有bitset
操作,直到单个movl
指令。
应用@ GlennTeitelbaum的建议,我也进行了第二次测试。 这一个消除了volatile
通过初始化可变bitset
从argc
,并且从返回的计算值main
:
#include <bitset>
int main ( int argc, char *argv[] )
{
std::bitset<32> bit32 = argc;
bit32[4].flip();
bit32[0] = 1;
return bit32.to_ulong();
}
这个生成了以下编译器输出(与上面相同的标志):
main:
.LFB958:
.cfi_startproc
movl %edi, %eax
xorl $16, %eax
orq $1, %rax
ret
请注意,在编译时不知道bitset
的实际初始化值时,它确实优化了最小的计算步骤数( xorl
后跟orl
)。 第三条指令( movl %edi, %eax
)只是将argc
从到达的寄存器移到要返回结果的寄存器中。
如果你担心调用函数,为什么要使用bitset?
怎么样
unsigned int bit32; // Assume int is 32 bits
bit32 = 0xf0f0f0f0;
bit32 ^= 16;
bit32 |= 1;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.