[英]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.