RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
cpu-cache-line-size.cpp
Go to the documentation of this file.
1#include <cerrno>
2#include <cstdint>
3#include <iostream>
4#include <optional>
5
6#if defined(__unix__)
7#include <unistd.h>
8#endif
9
10#if defined(__GLIBC__)
11#include <elf.h>
12#endif
13
14#if defined(_POSIX_C_SOURCE) && defined(_SC_LEVEL1_DCACHE_LINESIZE)
15static std::optional<int64_t> get_cachelinesize_from_sysconf() {
16 long val = ::sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
17 if (val == -1) // On error, -1 is returned.
18 return std::nullopt;
19 return val;
20}
21#else
22static std::optional<int64_t> get_cachelinesize_from_sysconf() {
23 return std::nullopt;
24}
25#endif
26
27#if defined(__GLIBC__)
28#include <sys/auxv.h>
29static std::optional<int64_t> get_cachelinesize_from_getauxval() {
30 unsigned long geometry = getauxval(AT_L1D_CACHEGEOMETRY);
31 if (geometry == 0 && errno == ENOENT) // On error, 0 is returned.
32 return std::nullopt;
33 geometry &= 0xFFFF; // cache line size in bytes in the bottom 16 bits.
34 return geometry;
35}
36#else
37static std::optional<int64_t> get_cachelinesize_from_getauxval() {
38 return std::nullopt;
39}
40#endif
41
42#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \
43 defined(__DragonFly__) || defined(__APPLE__)
44#include <cstddef>
45#include <sys/sysctl.h>
46#include <sys/types.h>
47static std::optional<int64_t> get_cachelinesize_from_sysctlbyname() {
48 int64_t val = 0;
49 size_t size = sizeof(val);
50 if (sysctlbyname("hw.cachelinesize", &val, &size, NULL, 0) != 0)
51 return std::nullopt;
52 return val;
53}
54#else
55static std::optional<int64_t> get_cachelinesize_from_sysctlbyname() {
56 return std::nullopt;
57}
58#endif
59
60#if defined(_WIN32) || defined(_WIN64)
61#include <cassert>
62#include <vector>
63//
64#include <Windows.h>
65static std::optional<int64_t>
67 DWORD buffer_size = 0;
68 GetLogicalProcessorInformation(nullptr, &buffer_size);
69 assert(buffer_size % sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) == 0);
70 std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> buffer(
71 buffer_size / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
72 GetLogicalProcessorInformation(buffer.data(), &buffer_size);
73 for (const auto& e : buffer) {
74 if (e.Relationship == RelationCache && e.Cache.Level == 1 &&
75 e.Cache.Type == CacheData) {
76 return e.Cache.LineSize;
77 }
78 }
79 return std::nullopt;
80}
81#else
82static std::optional<int64_t>
86#endif
87
88int main() {
89 std::optional<int64_t> val;
90 if (!val)
92 if (!val)
94 if (!val)
96 if (!val)
98#if defined(__riscv)
99 if (!val) {
100 // On RISC-V, at least on openSUSE TW, at least as of this commit,
101 // there is just no way to query this information.
102 val = 0; // Pretend we did detect it as zero. Will use fall back value.
103 }
104#endif
105 if (!val) {
106 std::cerr
107 << "Do not know how to query CPU L1d cache line size for this system!"
108 << std::endl;
109 return 1;
110 }
111 std::cout << *val << std::endl;
112 return 0;
113}
assert(dim.area() >=area)
static std::optional< int64_t > get_cachelinesize_from_GetLogicalProcessorInformation()
static std::optional< int64_t > get_cachelinesize_from_sysctlbyname()
static std::optional< int64_t > get_cachelinesize_from_sysconf()
int main()
static std::optional< int64_t > get_cachelinesize_from_getauxval()