1 //
2 // Copyright 2017 The Abseil Authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      https://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 // -----------------------------------------------------------------------------
17 // File: optimization.h
18 // -----------------------------------------------------------------------------
19 //
20 // This header file defines portable macros for performance optimization.
21 
22 #ifndef ABSL_BASE_OPTIMIZATION_H_
23 #define ABSL_BASE_OPTIMIZATION_H_
24 
25 #include "absl/base/config.h"
26 
27 // ABSL_BLOCK_TAIL_CALL_OPTIMIZATION
28 //
29 // Instructs the compiler to avoid optimizing tail-call recursion. Use of this
30 // macro is useful when you wish to preserve the existing function order within
31 // a stack trace for logging, debugging, or profiling purposes.
32 //
33 // Example:
34 //
35 //   int f() {
36 //     int result = g();
37 //     ABSL_BLOCK_TAIL_CALL_OPTIMIZATION();
38 //     return result;
39 //   }
40 #if defined(__pnacl__)
41 #define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; }
42 #elif defined(__clang__)
43 // Clang will not tail call given inline volatile assembly.
44 #define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("")
45 #elif defined(__GNUC__)
46 // GCC will not tail call given inline volatile assembly.
47 #define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("")
48 #elif defined(_MSC_VER)
49 #include <intrin.h>
50 // The __nop() intrinsic blocks the optimisation.
51 #define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __nop()
52 #else
53 #define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; }
54 #endif
55 
56 // ABSL_CACHELINE_SIZE
57 //
58 // Explicitly defines the size of the L1 cache for purposes of alignment.
59 // Setting the cacheline size allows you to specify that certain objects be
60 // aligned on a cacheline boundary with `ABSL_CACHELINE_ALIGNED` declarations.
61 // (See below.)
62 //
63 // NOTE: this macro should be replaced with the following C++17 features, when
64 // those are generally available:
65 //
66 //   * `std::hardware_constructive_interference_size`
67 //   * `std::hardware_destructive_interference_size`
68 //
69 // See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0154r1.html
70 // for more information.
71 #if defined(__GNUC__)
72 // Cache line alignment
73 #if defined(__i386__) || defined(__x86_64__)
74 #define ABSL_CACHELINE_SIZE 64
75 #elif defined(__powerpc64__)
76 #define ABSL_CACHELINE_SIZE 128
77 #elif defined(__aarch64__)
78 // We would need to read special register ctr_el0 to find out L1 dcache size.
79 // This value is a good estimate based on a real aarch64 machine.
80 #define ABSL_CACHELINE_SIZE 64
81 #elif defined(__arm__)
82 // Cache line sizes for ARM: These values are not strictly correct since
83 // cache line sizes depend on implementations, not architectures.  There
84 // are even implementations with cache line sizes configurable at boot
85 // time.
86 #if defined(__ARM_ARCH_5T__)
87 #define ABSL_CACHELINE_SIZE 32
88 #elif defined(__ARM_ARCH_7A__)
89 #define ABSL_CACHELINE_SIZE 64
90 #endif
91 #endif
92 
93 #ifndef ABSL_CACHELINE_SIZE
94 // A reasonable default guess.  Note that overestimates tend to waste more
95 // space, while underestimates tend to waste more time.
96 #define ABSL_CACHELINE_SIZE 64
97 #endif
98 
99 // ABSL_CACHELINE_ALIGNED
100 //
101 // Indicates that the declared object be cache aligned using
102 // `ABSL_CACHELINE_SIZE` (see above). Cacheline aligning objects allows you to
103 // load a set of related objects in the L1 cache for performance improvements.
104 // Cacheline aligning objects properly allows constructive memory sharing and
105 // prevents destructive (or "false") memory sharing.
106 //
107 // NOTE: this macro should be replaced with usage of `alignas()` using
108 // `std::hardware_constructive_interference_size` and/or
109 // `std::hardware_destructive_interference_size` when available within C++17.
110 //
111 // See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0154r1.html
112 // for more information.
113 //
114 // On some compilers, `ABSL_CACHELINE_ALIGNED` expands to an `__attribute__`
115 // or `__declspec` attribute. For compilers where this is not known to work,
116 // the macro expands to nothing.
117 //
118 // No further guarantees are made here. The result of applying the macro
119 // to variables and types is always implementation-defined.
120 //
121 // WARNING: It is easy to use this attribute incorrectly, even to the point
122 // of causing bugs that are difficult to diagnose, crash, etc. It does not
123 // of itself guarantee that objects are aligned to a cache line.
124 //
125 // NOTE: Some compilers are picky about the locations of annotations such as
126 // this attribute, so prefer to put it at the beginning of your declaration.
127 // For example,
128 //
129 //   ABSL_CACHELINE_ALIGNED static Foo* foo = ...
130 //
131 //   class ABSL_CACHELINE_ALIGNED Bar { ...
132 //
133 // Recommendations:
134 //
135 // 1) Consult compiler documentation; this comment is not kept in sync as
136 //    toolchains evolve.
137 // 2) Verify your use has the intended effect. This often requires inspecting
138 //    the generated machine code.
139 // 3) Prefer applying this attribute to individual variables. Avoid
140 //    applying it to types. This tends to localize the effect.
141 #define ABSL_CACHELINE_ALIGNED __attribute__((aligned(ABSL_CACHELINE_SIZE)))
142 #elif defined(_MSC_VER)
143 #define ABSL_CACHELINE_SIZE 64
144 #define ABSL_CACHELINE_ALIGNED __declspec(align(ABSL_CACHELINE_SIZE))
145 #else
146 #define ABSL_CACHELINE_SIZE 64
147 #define ABSL_CACHELINE_ALIGNED
148 #endif
149 
150 // ABSL_PREDICT_TRUE, ABSL_PREDICT_FALSE
151 //
152 // Enables the compiler to prioritize compilation using static analysis for
153 // likely paths within a boolean branch.
154 //
155 // Example:
156 //
157 //   if (ABSL_PREDICT_TRUE(expression)) {
158 //     return result;                        // Faster if more likely
159 //   } else {
160 //     return 0;
161 //   }
162 //
163 // Compilers can use the information that a certain branch is not likely to be
164 // taken (for instance, a CHECK failure) to optimize for the common case in
165 // the absence of better information (ie. compiling gcc with `-fprofile-arcs`).
166 //
167 // Recommendation: Modern CPUs dynamically predict branch execution paths,
168 // typically with accuracy greater than 97%. As a result, annotating every
169 // branch in a codebase is likely counterproductive; however, annotating
170 // specific branches that are both hot and consistently mispredicted is likely
171 // to yield performance improvements.
172 #if ABSL_HAVE_BUILTIN(__builtin_expect) || \
173     (defined(__GNUC__) && !defined(__clang__))
174 #define ABSL_PREDICT_FALSE(x) (__builtin_expect(x, 0))
175 #define ABSL_PREDICT_TRUE(x) (__builtin_expect(false || (x), true))
176 #else
177 #define ABSL_PREDICT_FALSE(x) (x)
178 #define ABSL_PREDICT_TRUE(x) (x)
179 #endif
180 
181 #endif  // ABSL_BASE_OPTIMIZATION_H_
182