Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Do likelihood attributes make sense with a single if statement?

Cppreference and this documentation do not state explicitly that likelihood attributes won’t work with a single if statement. Or, I just do not understand what is meant by alternative path of execution. So that’s my question, will the attribute, say, [[unlikely]], work in the case below?

if (condition) [[unlikely]] {
    do_stuff();
}

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Yes, it makes sense. The alternative, [[likely]], path is the one where the condition is false, that is, the path not calling do_stuff();. That becomes the path it’ll try to optimize for.

Example:

#include <iostream>

inline void do_stuff() {
    std::cout << "Surprise!\n";
}

int main(int argc, char**) {
    if (argc == 0) [[likely]] {
        do_stuff();
    }
}

Assembler with [[likely]]:

.LC0:
        .string "Surprise!\n"
main:
        test    edi, edi
        jne     .L4
        sub     rsp, 8
        mov     edx, 10
        mov     esi, OFFSET FLAT:.LC0
        mov     edi, OFFSET FLAT:_ZSt4cout
        call    std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)
        xor     eax, eax
        add     rsp, 8
        ret
.L4:
        xor     eax, eax
        ret
_GLOBAL__sub_I_main:
        sub     rsp, 8
        mov     edi, OFFSET FLAT:_ZStL8__ioinit
        call    std::ios_base::Init::Init() [complete object constructor]
        mov     edx, OFFSET FLAT:__dso_handle
        mov     esi, OFFSET FLAT:_ZStL8__ioinit
        mov     edi, OFFSET FLAT:_ZNSt8ios_base4InitD1Ev
        add     rsp, 8
        jmp     __cxa_atexit

With [[unlikely]] (and without attribute at all):

.LC0:
        .string "Surprise!\n"
main:
        test    edi, edi
        je      .L8
        xor     eax, eax
        ret
.L8:
        push    rax
        mov     edx, 10
        mov     esi, OFFSET FLAT:.LC0
        mov     edi, OFFSET FLAT:_ZSt4cout
        call    std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)
        xor     eax, eax
        pop     rdx
        ret
_GLOBAL__sub_I_main:
        sub     rsp, 8
        mov     edi, OFFSET FLAT:_ZStL8__ioinit
        call    std::ios_base::Init::Init() [complete object constructor]
        mov     edx, OFFSET FLAT:__dso_handle
        mov     esi, OFFSET FLAT:_ZStL8__ioinit
        mov     edi, OFFSET FLAT:_ZNSt8ios_base4InitD1Ev
        add     rsp, 8
        jmp     __cxa_atexit

Those are two slightly different outcomes and without knowing too much about assembler, I’d say the effect of putting [[likely]] there is clear. It looks to me that putting [[likely]] there made it inline the function while [[unlikely]] left it as a function call.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading