C++20协程帧未优化问题:嵌入式场景编译器帧大小异常咨询
C++20协程帧大小优化问题(嵌入式场景)
在嵌入式应用场景下测试C++20协程时,发现GCC和Clang在-O3优化级别下生成的协程帧大小超出理论最优值。以下是测试数据(co-await列中"yes"表示保留原代码的co-await语句,"commented"表示注释掉该语句):
| Compiler (-O3) | co-await | coroutine1 | coroutine4 |
|---|---|---|---|
| GCC 13.2 x86-64 | yes | 72 bytes | 144 bytes |
| clang 17.0.1 x86-64 | yes | 72 bytes | 136 bytes |
| GCC 13.2 x86-64 | commented | 80 bytes | 136 bytes |
| clang 17.0.1 x86-64 | commented | 32 bytes | 32 bytes |
我预期所有分配的帧大小应与最后一行数据相近甚至更小——缓冲区在co_await后不再使用,函数仅需保存fill函数指针和ret值即可。
请问是我的代码存在问题,还是由于C++20协程较新且复杂度高,编译器尚未实现良好的协程帧优化?恳请提供可行的解决方案。
测试代码
#include <coroutine> #include <iostream> #include <stdint.h> struct promise; static constexpr std::size_t bufSize=20; static int numArgc=0; static std::size_t allocatedSize=0; struct coroutine : std::coroutine_handle<promise> { using promise_type = ::promise; }; struct promise { coroutine get_return_object() { return {coroutine::from_promise(*this)}; } std::suspend_always initial_suspend() noexcept { return {}; } std::suspend_always final_suspend() noexcept { return {}; } void return_value(unsigned val) { sum=val; } void unhandled_exception() {} void* operator new(std::size_t size) { allocatedSize+=size; return malloc(size); } void operator delete(void* ptr, std::size_t size) { free(ptr); } unsigned sum=0; }; uint32_t sum(uint8_t *buffer) { uint32_t ret=0; for(std::size_t i=0;i<bufSize;i++) { ret+=buffer[i]; } return ret; } void fill(uint8_t *buffer) { for(std::size_t i=0;i<bufSize;i++) { buffer[i]=numArgc+i; } } coroutine coroutine1(void (*fill)(uint8_t *buffer)) { unsigned ret=0; { uint8_t buf[bufSize]={}; fill(buf); ret+=sum(buf); co_await std::suspend_always{}; // commented in "co-await: commented" } co_return ret; } coroutine coroutine4(void (*fill)(uint8_t *buffer)) { unsigned ret=0; { uint8_t buf[bufSize]={}; fill(buf); ret+=sum(buf); co_await std::suspend_always{}; // commented in "co-await: commented" } { uint8_t buf[bufSize]={}; fill(buf); ret+=sum(buf); co_await std::suspend_always{}; // commented in "co-await: commented" } { uint8_t buf[bufSize]={}; fill(buf); ret+=sum(buf); co_await std::suspend_always{}; // commented in "co-await: commented" } { uint8_t buf[bufSize]={}; fill(buf); ret+=sum(buf); co_await std::suspend_always{}; // commented in "co-await: commented" } co_return ret; } int main(int argc, char *argv[]) { numArgc=argc; auto h1=coroutine1(fill); while(!h1.done()) { h1.resume(); } std::cout<<"1 loop sum: "<<h1.promise().sum<<" Allocated:"<<allocatedSize<<" bytes\n"; allocatedSize=0; auto h4=coroutine4(fill); while(!h4.done()) { h4.resume(); } std::cout<<"4 loops sum: "<<h4.promise().sum<<" Allocated:"<<allocatedSize<<" bytes\n"; }
内容的提问来源于stack exchange,提问作者Alessandro M
相关产品推荐
相关产品推荐

