Skip to content

Compilation time of coroutine grows non-linearly #58650

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
dyzsr opened this issue Oct 27, 2022 · 5 comments
Closed

Compilation time of coroutine grows non-linearly #58650

dyzsr opened this issue Oct 27, 2022 · 5 comments
Assignees
Labels
coroutines C++20 coroutines

Comments

@dyzsr
Copy link

dyzsr commented Oct 27, 2022

In clang 15.0.3, the compilation time of coroutine seems to grow non-linearly against code size (I have tested on linux and macOS).

Here are the simplified examples I generated.

  • task.h which defines the coroutine data structures:
#include <coroutine>

struct promise;

struct task : std::coroutine_handle<promise> {
  using promise_type = struct promise;
};

struct promise {
  task get_return_object() { return {task::from_promise(*this)}; }
  std::suspend_always initial_suspend() noexcept { return {}; }
  std::suspend_always final_suspend() noexcept { return {}; }
  void return_void() noexcept {}
  void unhandled_exception() {}
};
  • gen.cpp which generates the coroutine use cases:
#include <cassert>
#include <cstdio>
#include <cstdlib>

int main(int argc, char **argv) {
  assert(argc == 2);
  int n = atoi(argv[1]);
  printf("#include <cstdio>\n");
  printf("#include \"task.h\"\n");
  printf("task t() {\n");
  for (int i = 1; i <= n; i++) printf("int cond_%d = 1;\n", i);
  printf("int val = 0;\n");
  for (int i = 1; i <= n; i++) printf("if (cond_%d) val++;\n", i);
  printf("printf(\"%%d\\n\", val);\n");
  printf("co_return;\n");
  printf("}\n");
  return 0;
}
  • test.sh used to run the test:
#!/bin/sh

clang++ -o gen gen.cpp
for i in 2000 4000 6000 8000 10000 12000 14000 16000 18000 20000
do
  printf "n: %d\n" $i
  ./gen $i > a.cpp
  time clang++ -c a.cpp -std=c++20 -stdlib=libc++
  printf "\n"
done

The generated a.cpp is like:

#include <cstdio>
#include "task.h"
task t() {
int cond_1 = 1;
int cond_2 = 1;
int cond_3 = 1;
...
int val = 0;
if (cond_1) val++;
if (cond_2) val++;
if (cond_3) val++;
...
printf("%d\n", val);
co_return;
}

My test result:

n: 2000

real	0m2.697s
user	0m2.583s
sys	0m0.105s

n: 4000

real	0m8.662s
user	0m8.314s
sys	0m0.332s

n: 6000

real	0m19.107s
user	0m18.330s
sys	0m0.734s

n: 8000

real	0m35.622s
user	0m34.018s
sys	0m1.436s

n: 10000

real	0m50.344s
user	0m48.158s
sys	0m1.959s

n: 12000

real	1m12.844s
user	1m9.896s
sys	0m2.728s

n: 14000

real	1m57.271s
user	1m52.938s
sys	0m4.076s

n: 16000

real	2m42.044s
user	2m35.904s
sys	0m5.635s

n: 18000

real	3m28.608s
user	3m20.904s
sys	0m7.057s

n: 20000

real	4m6.561s
user	3m56.836s
sys	0m9.012s

The compilation speed is really slow for very large coroutines (which can be generated by program in our use cases).

@EugeneZelenko EugeneZelenko added coroutines C++20 coroutines and removed new issue labels Oct 27, 2022
@llvmbot
Copy link
Member

llvmbot commented Oct 27, 2022

@llvm/issue-subscribers-coroutines

@ChuanqiXu9 ChuanqiXu9 self-assigned this Oct 28, 2022
@ChuanqiXu9
Copy link
Member

Thanks for the reporting! It is concise and interesting. I'll take a look.

@yurai007
Copy link
Contributor

yurai007 commented Jan 2, 2023

Proposed fix: https://reviews.llvm.org/D140818

@ChuanqiXu9
Copy link
Member

This one should be fixed by the above patch.

@microcai
Copy link

I was hited by this bug!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
coroutines C++20 coroutines
Projects
Status: No status
Development

No branches or pull requests

6 participants