20 #define _GNU_SOURCE 1 // for RTLD_NOLOAD 45 long numCpus = sysconf(_SC_NPROCESSORS_CONF);
86 auto raw = line.c_str();
88 unsigned long val = strtoul(raw, &end, 10);
89 if (end == raw || (*end !=
',' && *end !=
'-' && *end !=
'\n' && *end != 0)) {
90 throw std::runtime_error(
91 to<std::string>(
"error parsing list '", line,
"'").c_str());
103 std::vector<std::vector<size_t>> equivClassesByCpu;
105 std::vector<size_t> cpus;
108 auto cpu = cpus.size();
109 std::vector<size_t> levels;
110 for (
size_t index = 0;; ++index) {
112 sformat(
"/sys/devices/system/cpu/cpu{}/cache/index{}/", cpu, index);
113 auto cacheType = mapping(dir +
"type");
114 auto equivStr = mapping(dir +
"shared_cpu_list");
115 if (cacheType.size() == 0 || equivStr.size() == 0) {
119 if (cacheType[0] ==
'I') {
124 auto level = levels.size();
125 levels.push_back(equiv);
130 while (numCachesByLevel.size() <= level) {
131 numCachesByLevel.push_back(0);
133 numCachesByLevel[level]++;
137 if (levels.size() == 0) {
141 equivClassesByCpu.emplace_back(
std::move(levels));
145 if (cpus.size() == 0) {
146 throw std::runtime_error(
"unable to load cache sharing info");
149 std::sort(cpus.begin(), cpus.end(), [&](
size_t lhs,
size_t rhs) ->
bool {
154 auto& lhsEquiv = equivClassesByCpu[lhs];
155 auto& rhsEquiv = equivClassesByCpu[
rhs];
156 for (ssize_t
i = ssize_t(
std::min(lhsEquiv.size(), rhsEquiv.size())) - 1;
159 auto idx = size_t(
i);
160 if (lhsEquiv[idx] != rhsEquiv[idx]) {
161 return lhsEquiv[idx] < rhsEquiv[idx];
172 std::vector<size_t> indexes(cpus.size());
173 for (
size_t i = 0;
i < cpus.size(); ++
i) {
174 indexes[cpus[
i]] =
i;
183 std::ifstream xi(name.c_str());
199 for (
size_t cpu = 0; cpu <
numCpus; ++cpu) {
209 #if !FOLLY_HAVE_LINUX_VDSO 212 void*
h = dlopen(
"linux-vdso.so.1", RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
218 if (func ==
nullptr) {
231 template struct SequentialThreadId<std::atomic>;
239 : allocSize_{allocSize},
sz_(sz) {}
242 std::lock_guard<std::mutex>
g(
m_);
252 throw_exception<std::bad_alloc>();
265 assert(intptr_t(mem) % 128 != 0);
SimpleAllocator(size_t allocSize, size_t sz)
static CacheLocality uniform(size_t numCpus)
std::vector< size_t > localityIndexByCpu
std::string sformat(StringPiece fmt, Args &&...args)
void aligned_free(void *aligned_ptr)
constexpr detail::Map< Move > move
void BENCHFUN() getline(size_t iters, size_t arg)
—— Concurrent Priority Queue Implementation ——
FOLLY_PUSH_WARNING RHS rhs
constexpr std::size_t max_align_v
void * aligned_malloc(size_t size, size_t align)
auto end(TestAdlIterable &instance)
std::vector< size_t > numCachesByLevel
int(* Func)(unsigned *cpu, unsigned *node, void *unused)
Function pointer to a function with the same signature as getcpu(2).
cache index *static CacheLocality readFromSysfs()
static Func resolveVdsoFunc()
std::vector< void * > blocks_
static CacheLocality getSystemLocalityInfo()
Returns the best real CacheLocality information available.
static size_t parseLeadingNumber(const std::string &line)