/src/botan/src/lib/utils/prefetch.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * (C) 2023 Jack Lloyd |
3 | | * |
4 | | * Botan is released under the Simplified BSD License (see license.txt) |
5 | | */ |
6 | | |
7 | | #include <botan/internal/prefetch.h> |
8 | | |
9 | | #include <botan/internal/bit_ops.h> |
10 | | #include <new> |
11 | | |
12 | | namespace Botan { |
13 | | |
14 | 0 | uint64_t prefetch_array_raw(size_t bytes, const void* arrayv) noexcept { |
15 | | #if defined(__cpp_lib_hardware_interference_size) |
16 | | const size_t cache_line_size = std::hardware_destructive_interference_size; |
17 | | #else |
18 | | // We arbitrarily use a 64 byte cache line, which is by far the most |
19 | | // common size. |
20 | | // |
21 | | // Runtime detection adds too much overhead to this function. |
22 | 0 | const size_t cache_line_size = 64; |
23 | 0 | #endif |
24 | |
|
25 | 0 | const uint8_t* array = static_cast<const uint8_t*>(arrayv); |
26 | |
|
27 | 0 | volatile uint64_t combiner = 1; |
28 | |
|
29 | 0 | for(size_t idx = 0; idx < bytes; idx += cache_line_size) { |
30 | 0 | #if BOTAN_COMPILER_HAS_BUILTIN(__builtin_prefetch) |
31 | | // we have no way of knowing if the compiler will emit anything here |
32 | 0 | __builtin_prefetch(&array[idx]); |
33 | 0 | #endif |
34 | |
|
35 | 0 | combiner = combiner | array[idx]; |
36 | 0 | } |
37 | | |
38 | | /* |
39 | | * The combiner variable is initialized with 1, and we accumulate using OR, so |
40 | | * now combiner must be a value other than zero. This being the case we will |
41 | | * always return zero here. Hopefully the compiler will not figure this out. |
42 | | */ |
43 | 0 | return ct_is_zero(combiner); |
44 | 0 | } |
45 | | |
46 | | } // namespace Botan |