facebookexperimental / facebookexperimental/libunifex
unifex task/timed_single_thread_context cannot run 1 million concurrent tasks
- 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
Assessment
This issue has not been assessed yet.