|
|
|||
Warning, file /include/absl/base/prefetch.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 // Copyright 2023 The Abseil Authors 0002 // 0003 // Licensed under the Apache License, Version 2.0 (the "License"); 0004 // you may not use this file except in compliance with the License. 0005 // You may obtain a copy of the License at 0006 // 0007 // https://www.apache.org/licenses/LICENSE-2.0 0008 // 0009 // Unless required by applicable law or agreed to in writing, software 0010 // distributed under the License is distributed on an "AS IS" BASIS, 0011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 0012 // See the License for the specific language governing permissions and 0013 // limitations under the License. 0014 // 0015 // ----------------------------------------------------------------------------- 0016 // File: prefetch.h 0017 // ----------------------------------------------------------------------------- 0018 // 0019 // This header file defines prefetch functions to prefetch memory contents 0020 // into the first level cache (L1) for the current CPU. The prefetch logic 0021 // offered in this header is limited to prefetching first level cachelines 0022 // only, and is aimed at relatively 'simple' prefetching logic. 0023 // 0024 #ifndef ABSL_BASE_PREFETCH_H_ 0025 #define ABSL_BASE_PREFETCH_H_ 0026 0027 #include "absl/base/attributes.h" 0028 #include "absl/base/config.h" 0029 0030 #if defined(ABSL_INTERNAL_HAVE_SSE) 0031 #include <xmmintrin.h> 0032 #endif 0033 0034 #if defined(_MSC_VER) 0035 #include <intrin.h> 0036 #if defined(ABSL_INTERNAL_HAVE_SSE) 0037 #pragma intrinsic(_mm_prefetch) 0038 #endif 0039 #endif 0040 0041 namespace absl { 0042 ABSL_NAMESPACE_BEGIN 0043 0044 // Moves data into the L1 cache before it is read, or "prefetches" it. 0045 // 0046 // The value of `addr` is the address of the memory to prefetch. If 0047 // the target and compiler support it, data prefetch instructions are 0048 // generated. If the prefetch is done some time before the memory is 0049 // read, it may be in the cache by the time the read occurs. 0050 // 0051 // This method prefetches data with the highest degree of temporal locality; 0052 // data is prefetched where possible into all levels of the cache. 0053 // 0054 // Incorrect or gratuitous use of this function can degrade performance. 0055 // Use this function only when representative benchmarks show an improvement. 0056 // 0057 // Example: 0058 // 0059 // // Computes incremental checksum for `data`. 0060 // int ComputeChecksum(int sum, absl::string_view data); 0061 // 0062 // // Computes cumulative checksum for all values in `data` 0063 // int ComputeChecksum(absl::Span<const std::string> data) { 0064 // int sum = 0; 0065 // auto it = data.begin(); 0066 // auto pit = data.begin(); 0067 // auto end = data.end(); 0068 // for (int dist = 8; dist > 0 && pit != data.end(); --dist, ++pit) { 0069 // absl::PrefetchToLocalCache(pit->data()); 0070 // } 0071 // for (; pit != end; ++pit, ++it) { 0072 // sum = ComputeChecksum(sum, *it); 0073 // absl::PrefetchToLocalCache(pit->data()); 0074 // } 0075 // for (; it != end; ++it) { 0076 // sum = ComputeChecksum(sum, *it); 0077 // } 0078 // return sum; 0079 // } 0080 // 0081 void PrefetchToLocalCache(const void* addr); 0082 0083 // Moves data into the L1 cache before it is read, or "prefetches" it. 0084 // 0085 // This function is identical to `PrefetchToLocalCache()` except that it has 0086 // non-temporal locality: the fetched data should not be left in any of the 0087 // cache tiers. This is useful for cases where the data is used only once / 0088 // short term, for example, invoking a destructor on an object. 0089 // 0090 // Incorrect or gratuitous use of this function can degrade performance. 0091 // Use this function only when representative benchmarks show an improvement. 0092 // 0093 // Example: 0094 // 0095 // template <typename Iterator> 0096 // void DestroyPointers(Iterator begin, Iterator end) { 0097 // size_t distance = std::min(8U, bars.size()); 0098 // 0099 // int dist = 8; 0100 // auto prefetch_it = begin; 0101 // while (prefetch_it != end && --dist;) { 0102 // absl::PrefetchToLocalCacheNta(*prefetch_it++); 0103 // } 0104 // while (prefetch_it != end) { 0105 // delete *begin++; 0106 // absl::PrefetchToLocalCacheNta(*prefetch_it++); 0107 // } 0108 // while (begin != end) { 0109 // delete *begin++; 0110 // } 0111 // } 0112 // 0113 void PrefetchToLocalCacheNta(const void* addr); 0114 0115 // Moves data into the L1 cache with the intent to modify it. 0116 // 0117 // This function is similar to `PrefetchToLocalCache()` except that it 0118 // prefetches cachelines with an 'intent to modify' This typically includes 0119 // invalidating cache entries for this address in all other cache tiers, and an 0120 // exclusive access intent. 0121 // 0122 // Incorrect or gratuitous use of this function can degrade performance. As this 0123 // function can invalidate cached cachelines on other caches and computer cores, 0124 // incorrect usage of this function can have an even greater negative impact 0125 // than incorrect regular prefetches. 0126 // Use this function only when representative benchmarks show an improvement. 0127 // 0128 // Example: 0129 // 0130 // void* Arena::Allocate(size_t size) { 0131 // void* ptr = AllocateBlock(size); 0132 // absl::PrefetchToLocalCacheForWrite(ptr); 0133 // return ptr; 0134 // } 0135 // 0136 void PrefetchToLocalCacheForWrite(const void* addr); 0137 0138 #if ABSL_HAVE_BUILTIN(__builtin_prefetch) || defined(__GNUC__) 0139 0140 #define ABSL_HAVE_PREFETCH 1 0141 0142 // See __builtin_prefetch: 0143 // https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html. 0144 // 0145 ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCache( 0146 const void* addr) { 0147 __builtin_prefetch(addr, 0, 3); 0148 } 0149 0150 ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCacheNta( 0151 const void* addr) { 0152 __builtin_prefetch(addr, 0, 0); 0153 } 0154 0155 ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCacheForWrite( 0156 const void* addr) { 0157 // [x86] gcc/clang don't generate PREFETCHW for __builtin_prefetch(.., 1) 0158 // unless -march=broadwell or newer; this is not generally the default, so we 0159 // manually emit prefetchw. PREFETCHW is recognized as a no-op on older Intel 0160 // processors and has been present on AMD processors since the K6-2. 0161 #if defined(__x86_64__) && !defined(__PRFCHW__) 0162 asm("prefetchw %0" : : "m"(*reinterpret_cast<const char*>(addr))); 0163 #else 0164 __builtin_prefetch(addr, 1, 3); 0165 #endif 0166 } 0167 0168 #elif defined(ABSL_INTERNAL_HAVE_SSE) 0169 0170 #define ABSL_HAVE_PREFETCH 1 0171 0172 ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCache( 0173 const void* addr) { 0174 _mm_prefetch(reinterpret_cast<const char*>(addr), _MM_HINT_T0); 0175 } 0176 0177 ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCacheNta( 0178 const void* addr) { 0179 _mm_prefetch(reinterpret_cast<const char*>(addr), _MM_HINT_NTA); 0180 } 0181 0182 ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCacheForWrite( 0183 const void* addr) { 0184 #if defined(_MM_HINT_ET0) 0185 _mm_prefetch(reinterpret_cast<const char*>(addr), _MM_HINT_ET0); 0186 #elif !defined(_MSC_VER) && defined(__x86_64__) 0187 // _MM_HINT_ET0 is not universally supported. As we commented further 0188 // up, PREFETCHW is recognized as a no-op on older Intel processors 0189 // and has been present on AMD processors since the K6-2. We have this 0190 // disabled for MSVC compilers as this miscompiles on older MSVC compilers. 0191 asm("prefetchw %0" : : "m"(*reinterpret_cast<const char*>(addr))); 0192 #endif 0193 } 0194 0195 #else 0196 0197 ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCache( 0198 const void* addr) {} 0199 ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCacheNta( 0200 const void* addr) {} 0201 ABSL_ATTRIBUTE_ALWAYS_INLINE inline void PrefetchToLocalCacheForWrite( 0202 const void* addr) {} 0203 0204 #endif 0205 0206 ABSL_NAMESPACE_END 0207 } // namespace absl 0208 0209 #endif // ABSL_BASE_PREFETCH_H_
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|