1 // Copyright 2016 Google Inc. All rights reserved 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // +build ignore 16 17 #include "affinity.h" 18 19 #include "flags.h" 20 #include "log.h" 21 22 #ifdef __linux__ 23 24 #include <random> 25 26 #include <sched.h> 27 #include <sys/types.h> 28 #include <unistd.h> 29 30 void SetAffinityForSingleThread() { 31 cpu_set_t cs; 32 CPU_ZERO(&cs); 33 std::random_device generator; 34 std::uniform_int_distribution<int> distribution(0, g_flags.num_cpus - 1); 35 int cpu = distribution(generator); 36 37 // Try to come up with a CPU and one close to it. This should work on most 38 // hyperthreaded system, but may be less optimal under stranger setups. 39 // Choosing two completely different CPUs would work here as well, it's just a 40 // couple percent faster if they're close (and still faster than letting the 41 // scheduler do whatever it wants). 42 cpu = cpu - (cpu % 2); 43 CPU_SET(cpu, &cs); 44 if (g_flags.num_cpus > 1) 45 CPU_SET(cpu + 1, &cs); 46 47 if (sched_setaffinity(0, sizeof(cs), &cs) < 0) 48 WARN("sched_setaffinity: %s", strerror(errno)); 49 } 50 51 void SetAffinityForMultiThread() { 52 cpu_set_t cs; 53 CPU_ZERO(&cs); 54 for (int i = 0; i < g_flags.num_cpus; i++) { 55 CPU_SET(i, &cs); 56 } 57 if (sched_setaffinity(0, sizeof(cs), &cs) < 0) 58 WARN("sched_setaffinity: %s", strerror(errno)); 59 } 60 61 #else 62 63 void SetAffinityForSingleThread() {} 64 void SetAffinityForMultiThread() {} 65 66 #endif 67