facebookexperimental / facebookexperimental/libunifex

unifex task/timed_single_thread_context cannot run 1 million concurrent tasks

Open
#648 4 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
1.7k
Forks
210
PR merge metrics
No merged PRs in 30d

Description

https://github.com/Xavorim/cpp_tasks_bench?tab=readme-ov-file#results-on-my-system benchmarks libunifex against a few other concurrency libraries. The benchmark attempts to launch 1 million concurrent tasks. Unfortunately, the benchmark states libunifex hangs at just 100K tasks. I am able to replicate this myself, with the benchmark program at 100% for a minute until I killed the program.

I reimplemented the benchmark with `async_manual_reset_event` instead of `timed_single_thread_context`, and I am able to launch 1 million tasks in about 4 seconds: https://github.com/Xavorim/cpp_tasks_bench/pull/1

I'm entering this issue to see if the timer scheduler can be improved. I'll also compare against stdexec (as the benchmark repo doesn't include it currently).

## stdexec benchmark

stdexec appears to be able to run 1 million tasks with `exec::timed_thread_context`

```
#include
#include
#include
#include

#include
#include
#include
#include
#include

exec::timed_thread_context TIMER;

auto async_sleep(auto s) { return exec::schedule_after(TIMER.get_scheduler(), s); }

int main(int argc, char **argv) {
if (argc < 2) {
fprintf(stderr,
"Please specify the number of tasks\n"
"example: %s 10000\n",
argv[0]);
return EXIT_FAILURE;
}

exec::async_scope scope;
for (auto i : std::views::iota(0, std::stoi(argv[1]))) {
scope.spawn([]() -> exec::task { co_await async_sleep(std::chrono::seconds(10)); }());
}

stdexec::sync_wait(scope.on_empty());
return 0;
}
```

```
$ time ./a.out 1000000

real 0m17.098s
user 0m11.241s
sys 0m4.150s
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.