You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++20协程帧未优化问题:嵌入式场景编译器帧大小异常咨询

C++20协程帧大小优化问题(嵌入式场景)

在嵌入式应用场景下测试C++20协程时,发现GCC和Clang在-O3优化级别下生成的协程帧大小超出理论最优值。以下是测试数据(co-await列中"yes"表示保留原代码的co-await语句,"commented"表示注释掉该语句):

Compiler (-O3)co-awaitcoroutine1coroutine4
GCC 13.2 x86-64yes72 bytes144 bytes
clang 17.0.1 x86-64yes72 bytes136 bytes
GCC 13.2 x86-64commented80 bytes136 bytes
clang 17.0.1 x86-64commented32 bytes32 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 20:55:35