This is an archive of the discontinued LLVM Phabricator instance.

[Fuzzer] First step to thread affinity
AbandonedPublic

Authored by devnexen on Jun 9 2018, 2:28 AM.

Details

Reviewers
kcc
morehouse
Summary
  • Adding a new option (two modes) for a given job to be bound to a specific cpu.
  • No complex cpu binding, later on checking cpu load before binding, ought to be possible for example.
  • Linux and FreeBSD implemented at the moment.

Diff Detail

Event Timeline

devnexen created this revision.Jun 9 2018, 2:28 AM
Herald added subscribers: Restricted Project, llvm-commits, krytarowski, emaste. ยท View Herald TranscriptJun 9 2018, 2:28 AM

Intentionally implemented only on platforms I could test even though I know NetBSD for example has a very similar API. Windows is doable as well, their API is pretty straightforward, if anybody implements it further or later on I can grab a windows VM.

devnexen edited the summary of this revision. (Show Details)Jun 9 2018, 2:31 AM

What's the gain? Performance improvement? What are the numbers for benchmarking?

dvyukov added a subscriber: dvyukov.Jun 9 2018, 2:36 AM

What's the gain? Performance improvement? What are the numbers for benchmarking?

I wonder too.
Looks like something to fix in kernel. Each and every program out there is not supposed to do this to get good performance. That's OS job. OS knows what's the current load, what other apps are running, what's their affinity. LibFuzzer doesn't.

I understand your points, but usually see the jobs are often bound to cpu0 while this cpu can be potentially pretty busy.
But I put it as an option it s something not to be forced.

I understand your points, but usually see the jobs are often bound to cpu0 while this cpu can be potentially pretty busy.
But I put it as an option it s something not to be forced.

In general we are adding CPU/OS specific code, not sure whether it's worth the maintenance cost.

NetBSD uses similar but different API.. if it is really needed I would rather prompt for higher level 3rd party library.. but it might be overkill. Also reimplementing it opencoding might be overkill too.

If you want to bind fuzzing to cpu1, you can use userland cpu affinity tools to do it without changing the code.

I understand your points, but usually see the jobs are often bound to cpu0 while this cpu can be potentially pretty busy.

Whoever is doing this needs to be fixed.
It's exactly this kind of code that introduces such problems. It tries to be "smart" but does not have full picture. And we are adding more such code, so we will have more such problems. If one uses rand mode and 2 threads happens to be bound to the same core, we lose half of performance. The sequential mode occupies cores sequentially, so two independent processes will oversubscribe first half of cores and leave remaining cores idle.
If you are adding these flags to some scripts, you can just use taskset there.

I understand your points, but usually see the jobs are often bound to cpu0 while this cpu can be potentially pretty busy.

Whoever is doing this needs to be fixed.
It's exactly this kind of code that introduces such problems. It tries to be "smart" but does not have full picture. And we are adding more such code, so we will have more such problems. If one uses rand mode and 2 threads happens to be bound to the same core, we lose half of performance. The sequential mode occupies cores sequentially, so two independent processes will oversubscribe first half of cores and leave remaining cores idle.
If you are adding these flags to some scripts, you can just use taskset there.

True ideally what I tried to say in the description is ideally the cpu load ought to be checked first but that s a lot of code :-)

True ideally what I tried to say in the description is ideally the cpu load ought to be checked first but that s a lot of code :-)

No, you can't solve this by checking CPU load. Load, affinity, set of other processes and their affinity changes dynamically. And this can't be solved by periodic re-tuning either, because re-tuning logic of other processes is unknown. Only OS has the information and means to do this properly and efficiently.

Well on Linux you can check process infos on /proc/<proc>/status I believe but that might be overkill.

Well on Linux you can check process infos on /proc/<proc>/status I believe but that might be overkill.

Besides this being overkill, it also does not provide enough info. And you simply may not have permissions to read it. And you may be running inside of pid namespace. And two processes can do lock-step dense: both overload cpu 0, both decide to jump to cpu 1, both overload cpu 1, both decide to jump to cpu 0, etc.

Only OS has the information and means to do this properly and efficiently.

And we did not even get to windows, mac, fuchsia and akaros.

This is absolutely not the business we want to get into with libfuzzer. Moreover, this is absolutely not libfuzzer-specific. Reimplementing OS within each and every program out there is wrong.

devnexen abandoned this revision.Jun 9 2018, 3:33 AM

Ok fair points :-)