diff options
| author | Dan Willemsen <dwillemsen@google.com> | 2017-02-22 23:59:06 -0800 |
|---|---|---|
| committer | Dan Willemsen <dwillemsen@google.com> | 2017-02-23 18:41:50 -0800 |
| commit | 5db7f7c46b94424be56db9aa5af4ae537252a703 (patch) | |
| tree | b011cb652dfe9a917fa7dacfff8a977f3729f820 | |
| parent | f8e155865652181a504d7400afd25f35cf158472 (diff) | |
Randomize cpu affinity
Continue to lock kati to one or two CPUs, but pick one CPU at random,
and pick another CPU next to it. This dramatically speeds up cases where
more than one Kati instance is running at a time.
There's a multiproduct_build tool in Android that attempts to run Kati
on every build configuration present in the tree. My machine has 48
(including hyperthreading) cpu cores, with 64GB of ram. Before this
change, it would take ~12 minutes to build all 59 configurations, 12 at
a time. After this change it takes 3 minutes.
There doesn't seem to be any significant change in timings for
standalone builds. It looks like there was 1-2% difference with my
previous change that chose two completely random CPUs, but choosing two
that are likely hyperthreaded, or at least on the same chip helps.
| -rw-r--r-- | affinity.cc | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/affinity.cc b/affinity.cc index 2101fdb..5448b29 100644 --- a/affinity.cc +++ b/affinity.cc @@ -21,15 +21,29 @@ #ifdef __linux__ +#include <random> + #include <sched.h> +#include <sys/types.h> +#include <unistd.h> void SetAffinityForSingleThread() { cpu_set_t cs; CPU_ZERO(&cs); - int n = g_flags.num_cpus / 2; - CPU_SET(n, &cs); - if (n > 1) - CPU_SET(n + 1, &cs); + std::default_random_engine generator(getpid()); + std::uniform_int_distribution<int> distribution(0,g_flags.num_cpus-1); + int cpu = distribution(generator); + + // Try to come up with a CPU and one close to it. This should work on most + // hyperthreaded system, but may be less optimal under stranger setups. + // Choosing two completely different CPUs would work here as well, it's just a + // couple percent faster if they're close (and still faster than letting the + // scheduler do whatever it wants). + cpu = cpu - (cpu % 2); + CPU_SET(cpu, &cs); + if (g_flags.num_cpus > 1) + CPU_SET(cpu+1, &cs); + if (sched_setaffinity(0, sizeof(cs), &cs) < 0) WARN("sched_setaffinity: %s", strerror(errno)); } |
