關於bit操作(bit_set test_bit)

來源:互聯網
上載者:User

 

   今天發現一個奇怪的現象,用linux核心的bitops.h裡面的bit_set和test_bit居然沒有不用彙編的代碼快。記錄下來,備忘。    下面是可執行程式,THUIRDB暫時沒有bitops裡面的實現,改用我自己寫的實現了。當然bitops裡的實現,nr可以很大,而My Codenr只能是0-63之間的一個數,對THUIRDB的應用來說,足夠了。#include "stdint.h"#include <iostream>using namespace std;#define BITOP_ADDR(x) "=m" (*(volatile long *) (x))#define ADDR                            BITOP_ADDR(addr)#ifdef CONFIG_SMP#define LOCK_PREFIX /                ".section .smp_locks,/"a/"/n"   /                _ASM_ALIGN "/n"                 /                _ASM_PTR "661f/n" /                ".previous/n"                   /                "661:/n/tlock; "#else#define LOCK_PREFIX ""#endifstatic inline voidset_bit(unsigned int nr, volatile unsigned long *addr){        __asm__ volatile(LOCK_PREFIX "bts %1,%0"                   : BITOP_ADDR(addr) : "Ir" (nr) : "memory");}static inline bool test_bit(int nr, volatile const unsigned long *addr){        int oldbit;        asm volatile("bt %2,%1/n/t"                     "sbb %0,%0"                     : "=r" (oldbit)                     : "m" (*(unsigned long *)addr), "Ir" (nr));        return oldbit!=0;}static  void _set_bit(int nr, uint64_t* addr){        addr[0] |= ( 1UL << nr);};static bool _test_bit(int nr,uint64_t* addr){        return  (0 < (addr[0] & (1UL<<nr)));};int main(void){        uint64_t bit_arr=0;        #ifdef T1        for(int i = 0; i<1000000;++i)        {                _set_bit(id,&bit_arr);        }        #endif        #ifdef T2        for(int i = 0; i<1000000;++i)        {                set_bit(id,&bit_arr);        }        #endif        #ifdef T3        for(int i = 0; i<1000000;++i)        {                _test_bit(id,&bit_arr);        }        #endif        #ifdef T4        for(int i = 0; i<1000000;++i)        {                test_bit(id,&bit_arr);        }        #endif        return 0;}以下是反組譯碼的結果,可以看出用核心的方法,代碼短小,但效率較低,用移位與或的方法代碼多,但效率高。000000000040067c <_ZL7set_bitjPVm>: //set_bit  40067c:       55                      push   %rbp  40067d:       48 89 e5                mov    %rsp,%rbp  400680:       89 7d fc                mov    % edi,-0x4(%rbp)  400683:       48 89 75 f0             mov    %rsi,-0x10(%rbp)  400687:       48 8b 45 f0             mov    -0x10(%rbp),%rax  40068b:       8b 55 fc                mov    -0x4(%rbp),% edx  40068e:       0f ab 10                bts    % edx,(%rax)  400691:       c9                      leaveq   400692:       c3                      retq   0000000000400693 <_ZL8test_bitiPVKm>://test_bit  400693:       55                      push   %rbp  400694:       48 89 e5                mov    %rsp,%rbp  400697:       89 7d ec                mov    % edi,-0x14(%rbp)  40069a:       48 89 75 e0             mov    %rsi,-0x20(%rbp)  40069e:       48 8b 45 e0             mov    -0x20(%rbp),%rax  4006a2:       8b 55 ec                mov    -0x14(%rbp),% edx  4006a5:       0f a3 10                bt     % edx,(%rax)  4006a8:       19 c0                   sbb    % eax,% eax  4006aa:       89 45 fc                mov    % eax,-0x4(%rbp)  4006ad:       83 7d fc 00             cmpl   $0x0,-0x4(%rbp)  4006b1:       0f 95 c0                setne  %al  4006b4:       c9                      leaveq   4006b5:       c3                      retq   00000000004006b6 <_ZL8_set_bitiPm>://_set_bit  4006b6:       55                      push   %rbp  4006b7:       48 89 e5                mov    %rsp,%rbp  4006ba:       53                      push   %rbx  4006bb:       89 7d f4                mov    % edi,-0xc(%rbp)  4006be:       48 89 75 e8             mov    %rsi,-0x18(%rbp)  4006c2:       48 8b 45 e8             mov    -0x18(%rbp),%rax  4006c6:       48 8b 10                mov    (%rax),%rdx  4006c9:       8b 45 f4                mov    -0xc(%rbp),% eax  4006cc:       bb 01 00 00 00          mov    $0x1,% ebx  4006d1:       48 89 de                mov    %rbx,%rsi  4006d4:       89 c1                   mov    % eax,% ecx  4006d6:       48 d3 e6                shl    %cl,%rsi  4006d9:       48 89 f0                mov    %rsi,%rax  4006dc:       48 09 c2                or     %rax,%rdx  4006df:       48 8b 45 e8             mov    -0x18(%rbp),%rax  4006e3:       48 89 10                mov    %rdx,(%rax)  4006e6:       5b                      pop    %rbx  4006e7:       c9                      leaveq   4006e8:       c3                      retq   00000000004006e9 <_ZL9_test_bitiPm>://_test_bit  4006e9:       55                      push   %rbp  4006ea:       48 89 e5                mov    %rsp,%rbp  4006ed:       53                      push   %rbx  4006ee:       89 7d f4                mov    % edi,-0xc(%rbp)  4006f1:       48 89 75 e8             mov    %rsi,-0x18(%rbp)  4006f5:       48 8b 45 e8             mov    -0x18(%rbp),%rax  4006f9:       48 8b 10                mov    (%rax),%rdx  4006fc:       8b 45 f4                mov    -0xc(%rbp),% eax  4006ff:       48 89 d3                mov    %rdx,%rbx  400702:       89 c1                   mov    % eax,% ecx  400704:       48 d3 eb                shr    %cl,%rbx  400707:       48 89 d8                mov    %rbx,%rax  40070a:       83 e0 01                and    $0x1,% eax  40070d:       5b                      pop    %rbx  40070e:       c9                      leaveq   40070f:       c3                      retq   T2用-O2最佳化後的代碼,內聯到main裡面從400910到40093b00000000004008f0 <main>:<br /> 4008f0: 55 push %rbp<br /> 4008f1: 31 c0 xor %eax,%eax<br /> 4008f3: 53 push %rbx<br /> 4008f4: 48 83 ec 18 sub $0x18,%rsp<br /> 4008f8: 48 8d 4c 24 08 lea 0x8(%rsp),%rcx<br /> 4008fd: 48 c7 44 24 08 00 00 movq $0x0,0x8(%rsp)<br /> 400904: 00 00<br /> 400906: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)<br /> 40090d: 00 00 00<br /> 400910: 89 c2 mov %eax,%edx<br /> 400912: 83 e2 3f and $0x3f,%edx<br /> 400915: 0f ab 11 bts %edx,(%rcx)<br /> 400918: 83 c0 01 add $0x1,%eax<br /> 40091b: 3d 40 42 0f 00 cmp $0xf4240,%eax<br /> 400920: 75 ee jne 400910 <main+0x20><br /> 400922: 48 8b 74 24 08 mov 0x8(%rsp),%rsi<br /> 400927: bf e0 0d 60 00 mov $0x600de0,%edi<br /> 40092c: e8 67 fe ff ff callq 400798 <_ZNSo9_M_insertImEERSoT_@plt><br /> 400931: 48 89 c3 mov %rax,%rbx<br /> 400934: 48 8b 00 mov (%rax),%rax<br /> 400937: 48 8b 40 e8 mov -0x18(%rax),%rax<br /> 40093b: 48 8b ac 03 f0 00 00 mov 0xf0(%rbx,%rax,1),%rbp<br /> 400942: 00<br /> 400943: 48 85 ed test %rbp,%rbp<br /> 400946: 74 3f je 400987 <main+0x97><br /> 400948: 80 7d 38 00 cmpb $0x0,0x38(%rbp)<br /> 40094c: 74 20 je 40096e <main+0x7e><br /> 40094e: 0f b6 45 43 movzbl 0x43(%rbp),%eax<br /> 400952: 48 89 df mov %rbx,%rdi<br /> 400955: 0f be f0 movsbl %al,%esi<br /> 400958: e8 5b fe ff ff callq 4007b8 <_ZNSo3putEc@plt><br /> 40095d: 48 89 c7 mov %rax,%rdi<br /> 400960: e8 23 fe ff ff callq 400788 <_ZNSo5flushEv@plt><br /> 400965: 48 83 c4 18 add $0x18,%rsp<br /> 400969: 31 c0 xor %eax,%eax<br /> 40096b: 5b pop %rbx<br /> 40096c: 5d pop %rbp<br /> 40096d: c3 retq<br /> 40096e: 48 89 ef mov %rbp,%rdi<br /> 400971: e8 c2 fd ff ff callq 400738 <_ZNKSt5ctypeIcE13_M_widen_initEv@plt><br /> 400976: 48 8b 45 00 mov 0x0(%rbp),%rax<br /> 40097a: be 0a 00 00 00 mov $0xa,%esi<br /> 40097f: 48 89 ef mov %rbp,%rdi<br /> 400982: ff 50 30 callq *0x30(%rax)<br /> 400985: eb cb jmp 400952 <main+0x62><br /> 400987: e8 9c fd ff ff callq 400728 <_ZSt16__throw_bad_castv@plt><br /> 40098c: 90 nop<br /> 40098d: 90 nop<br /> 40098e: 90 nop<br /> 40098f: 90 nop  

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.