Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      C++ attribute: likely, unlikely(since C++20)

      From cppreference.com
      <cpp‎ |language‎ |attributes
       
       
      C++ language
      General topics
      Flow control
      Conditional execution statements
      Iteration statements (loops)
      Jump statements
      Functions
      Function declaration
      Lambda function expression
      inline specifier
      Dynamic exception specifications(until C++17*)
      noexcept specifier(C++11)
      Exceptions
      Namespaces
      Types
      Specifiers
      constexpr(C++11)
      consteval(C++20)
      constinit(C++20)
      Storage duration specifiers
      Initialization
      Expressions
      Alternative representations
      Literals
      Boolean -Integer -Floating-point
      Character -String -nullptr(C++11)
      User-defined(C++11)
      Utilities
      Attributes(C++11)
      Types
      typedef declaration
      Type alias declaration(C++11)
      Casts
      Memory allocation
      Classes
      Class-specific function properties
      Special member functions
      Templates
      Miscellaneous
       
      Declarations
       
      Attributes
      (C++23)
      (C++11)(until C++26)
      (C++14)
      likely
      (C++20)
      (C++17)
      (C++11)
      unlikely
      (C++20)
       

      Allow the compiler to optimize for the case where paths of execution including that statement are more or less likely than any alternative path of execution that does not include such a statement.

      Contents

      [edit]Syntax

      [[likely]] (1)
      [[unlikely]] (2)

      [edit]Explanation

      These attributes may be applied to labels and statements (other than declaration-statements). They may not be simultaneously applied to the same label or statement.

      1) Applies to a statement to allow the compiler to optimize for the case where paths of execution including that statement are more likely than any alternative path of execution that does not include such a statement.
      2) Applies to a statement to allow the compiler to optimize for the case where paths of execution including that statement are less likely than any alternative path of execution that does not include such a statement.

      A path of execution is deemed to include a label if and only if it contains a jump to that label:

      int f(int i){switch(i){case1:[[fallthrough]];[[likely]]case2:return1;}return2;}

      i==2 is considered more likely than any other value ofi, but the[[likely]] has no effect on thei==1 case even though it falls through thecase2: label.

      [edit]Example

      Run this code
      #include <chrono>#include <cmath>#include <iomanip>#include <iostream>#include <random> namespace with_attributes{constexprdouble pow(double x,longlong n)noexcept{if(n>0)[[likely]]return x* pow(x, n-1);else[[unlikely]]return1;}constexprlonglong fact(longlong n)noexcept{if(n>1)[[likely]]return n* fact(n-1);else[[unlikely]]return1;}constexprdouble cos(double x)noexcept{constexprlonglong precision{16LL};double y{};for(auto n{0LL}; n< precision; n+= 2LL)[[likely]]            y+= pow(x, n)/(n& 2LL?-fact(n): fact(n));return y;}}// namespace with_attributes namespace no_attributes{constexprdouble pow(double x,longlong n)noexcept{if(n>0)return x* pow(x, n-1);elsereturn1;}constexprlonglong fact(longlong n)noexcept{if(n>1)return n* fact(n-1);elsereturn1;}constexprdouble cos(double x)noexcept{constexprlonglong precision{16LL};double y{};for(auto n{0LL}; n< precision; n+= 2LL)            y+= pow(x, n)/(n& 2LL?-fact(n): fact(n));return y;}}// namespace no_attributes double gen_random()noexcept{staticstd::random_device rd;staticstd::mt19937 gen(rd());staticstd::uniform_real_distribution<double> dis(-1.0,1.0);return dis(gen);} volatiledouble sink{};// ensures a side effect int main(){for(constauto x:{0.125,0.25,0.5,1./(1<<26)})std::cout<<std::setprecision(53)<<"x = "<< x<<'\n'<<std::cos(x)<<'\n'<< with_attributes::cos(x)<<'\n'<<(std::cos(x)== with_attributes::cos(x)?"equal":"differ")<<'\n'; auto benchmark=[](auto fun,auto rem){constauto start=std::chrono::high_resolution_clock::now();for(auto size{1ULL}; size!=10'000'000ULL;++size)            sink= fun(gen_random());conststd::chrono::duration<double> diff=std::chrono::high_resolution_clock::now()- start;std::cout<<"Time: "<<std::fixed<<std::setprecision(6)<< diff.count()<<" sec "<< rem<<std::endl;};     benchmark(with_attributes::cos,"(with attributes)");    benchmark(no_attributes::cos,"(without attributes)");    benchmark([](double t){returnstd::cos(t);},"(std::cos)");}

      Possible output:

      x = 0.1250.992197667229329005600391155894612893462181091308593750.99219766722932900560039115589461289346218109130859375equalx = 0.250.968912421710644733430228825454832985997200012207031250.96891242171064473343022882545483298599720001220703125equalx = 0.50.87758256189037275873943144688382744789123535156250.8775825618903727587394314468838274478912353515625equalx = 1.490116119384765625e-080.999999999999999888977697537484345957636833190917968750.99999999999999988897769753748434595763683319091796875equalTime: 0.579122 sec (with attributes)Time: 0.722553 sec (without attributes)Time: 0.425963 sec (std::cos)

      [edit]References

      • C++23 standard (ISO/IEC 14882:2024):
      • 9.12.7 Likelihood attributes [dcl.attr.likelihood]
      • C++20 standard (ISO/IEC 14882:2020):
      • 9.12.6 Likelihood attributes [dcl.attr.likelihood]
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/attributes/likely&oldid=174652"

      [8]ページ先頭

      ©2009-2025 Movatter.jp