各位老师好!

这是CPP面试冲刺周刊 (c++ weekly) 陪你一起快速冲击大厂面试 第7期

周刊目标

  • 不是成为C++专家,而是成为C++面试专家

本期内容

  • constexpr、内联函数、编译期元编程

在高性能 AI 推理引擎中,我们面对的挑战是:

  • 任务调度复杂:成百上千的推理请求,需要同时调度 GPU、CPU、异步 I/O

  • 数据流高吞吐:输入张量、输出张量频繁传递,拷贝代价巨大

  • 延迟敏感:毫秒级甚至微秒级延迟都会影响用户体验

传统方法:

  • 线程池:每个请求一个线程 → 线程切换开销高

  • 回调地狱:异步 I/O + GPU kernel → 代码复杂难维护

C++20 协程(coroutine) 的出现,让这些问题迎刃而解。

一、协程是什么

协程是一种用户态轻量级任务,可以:

  • 挂起:执行到某个点暂停,保存当前栈信息

  • 恢复:以后再恢复执行,不占用线程

区别于线程:

| 特性 | 线程 | 协程 |

| —- | ———— | ———— |

| 调度成本 | 内核线程切换开销高 | 用户态切换,开销极低 |

| 内存占用 | 栈固定大小,通常 1MB | 栈帧按需生成,内存小 |

| 异步编程 | 回调或 futures | 可以像同步一样写异步逻辑 |

C++20 核心关键字

  • co_await:挂起协程,等待结果

  • co_yield:生成器,逐步返回值

  • co_return:返回协程结果


二、任务调度应用

在 AI 推理引擎里,一个典型场景是 GPU 推理:

  1. CPU 收集请求 → 调度到 GPU

  2. GPU 执行推理 → 生成输出

  3. CPU 处理结果 → 返回给客户端

传统线程池需要:

  • 大量线程 → 上下文切换

  • 线程阻塞 → GPU 空闲率低

使用协程:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13

task<float> infer(InputTensor input) {

// 将任务挂起到 GPU 队列

auto result = co_await gpu_scheduler.schedule(input);

// 返回推理结果

co_return result;

}

特点

  • 挂起协程,不占用线程

  • GPU 执行期间 CPU 可以处理其他请求

  • 多任务调度逻辑像写同步代码一样清晰


零拷贝数据流

AI 推理通常涉及大张量(MB~GB 级别):

  • 如果每次都拷贝 → 内存带宽成为瓶颈

  • 协程配合 移动语义 + 内存池 可以实现零拷贝:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11

task<Tensor> preprocess(Tensor&& input) {

Tensor buf = co_await memory_pool.acquire(input.size());

buf = std::move(input); // 零拷贝转移

co_return buf;

}

  • Tensor 可以包含 GPU/CPU 共享内存指针

  • co_await 可以挂起协程等待内存池可用

  • 数据不拷贝,只移动指针 → 高吞吐


三、协程底层原理

C++20 协程的核心是 编译器生成状态机

  1. 编译器将协程函数 拆分成多个阶段

  2. 每个 co_await / co_yield 对应一个挂起点

  3. 状态机存储局部变量和挂起点信息

  4. 协程句柄 (std::coroutine_handle) 可以恢复执行

效果:

  • 不需要线程切换 → 用户态调度

  • 内存占用低 → 栈帧按需生成

  • 支持复杂异步依赖链 → 代码像写同步一样


四、在 AI 推理引擎的应用案例

| 场景 | 问题 | 协程解决方案 |

| ————— | ————- | ————————– |

| GPU 推理任务队列 | 线程阻塞,CPU 空闲浪费 | 协程挂起等待 GPU 完成,CPU 并发调度其他任务 |

| 数据预处理 / 后处理 | 张量拷贝占用带宽 | 移动语义 + 内存池实现零拷贝 |

| 异步 I/O 请求 | 回调地狱,逻辑复杂 | 协程顺序写法,易读易维护 |

| 批处理请求(batching) | 等待所有请求凑满批次再执行 | co_await 等待条件满足,统一调度 |

示例:协程批处理 GPU 推理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11

task<void> batch_infer(std::vector<Tensor>& inputs) {

auto batch = co_await batcher.wait_for_full_batch(inputs);

auto result = co_await gpu_scheduler.schedule(batch);

co_return process(result);

}

  • 协程挂起直到批次满 → CPU 不阻塞

  • GPU 执行期间 CPU 可以处理其他协程

  • 零拷贝传递输入输出张量 → 高吞吐低延迟


五、协程优势总结

  1. 轻量级任务调度
  • 不用大量线程,减少上下文切换开销
  1. 顺序风格异步编程
  • 异步逻辑像写同步代码一样自然
  1. 零拷贝数据流
  • 移动语义 + 内存池 + 协程挂起,实现高性能数据传递
  1. 高吞吐低延迟
  • CPU/GPU/IO 并行利用,任务挂起不阻塞线程

六、注意事项

  • 协程栈帧大小虽然小,但协程过多仍可能占用内存

  • 异步异常处理需要用 co_return / try/catch 包装

  • GPU 数据传递需要注意 同步和内存一致性


七、参考来源

  1. C++20 Standard – Coroutines

  2. CppCoro Library

  3. NVIDIA TensorRT 异步执行优化实践

  4. 《C++20 Coroutine 深入浅出》博客系列

  5. TiDB / Ceph 异步调度源码参考

面试准备心得

曾经有一个让我心跳加速的岗位放在我面前,
我没有珍惜。
等到别人拿到 offer 的那一刻,
我才追悔莫及!

人世间,最痛苦的事情,
不是没钱吃饭,
也不是没房没车,
而是——错过了那个能让我逆天改命的机会!

如果上天再给我一次机会,
我一定会对那个岗位说三个字:
“我要你!”

如果非要在这份“心动”上加一个期限,
一万年太久了……
我只想要——21天!

你可能面临两种选择

① 犹豫不前:准备到天荒地老

“这个岗位太难了,我先准备一下吧。”
于是你准备1天、1周、1个月、1年……
等再回头,3年就这样过去了

  • 每天忙着搬砖,没时间系统复习
  • 每次想起要准备,又感觉心里没底
  • 面试知识点更新太快,拿着旧地图找新机会 最后,错过了一次又一次心动的岗位。

② 盲目回答:机会就在眼前,却抓不住

终于等来一场面试,
你觉得问题很简单,张口就答,
结果用“几千元思维”回答“百万年薪岗位”。

  • 面试官问到C++底层实现,答不上来
  • 设计题说到高并发架构,没实战经验
  • 一紧张,连项目里真实做过的东西都讲不清

一次面试失利,也许就意味着和理想岗位失之交臂。

更残酷的是

在你犹豫的这几年里,
找工作的成本越来越高:

  • 一个部门、一个领导,可能坚持一年就被解散
  • 一个项目,可能在10年、20年后,
    曾经复杂的业务规则、先进的架构,早已被淘汰
  • 市场上新的技术和面试要求,每年都在不断升级

等你回过头来,发现不仅机会没了,
连准备的方向都变了

不是让你成为C++专家, 而是让你成为C++面试专家

不是让你疯狂学习新知识, 而是帮你重新整理已有知识
让你的能力与面试题精准对齐。

因为,21天就够了,
足够让我火力全开,

  • 一边补齐 C++ 知识点,
  • 一边刷爆经典面试题,
  • 一边撸穿开源项目,
  • 让自己变得不可替代!

核心方法论

让你学到每个 c++知识,都关联一个经典面试,并对对应开源项目实践

  • 系统备战
    每天 20~30 分钟,聚焦 C++ 核心知识,
    三周时间完成高效梳理。

  • 经典面试题
    每个知识点都关联一个高频面试题
    让你知道“为什么考”和“怎么答”。

  • 开源项目实践
    通过真实项目理解底层原理,
    不背答案,而是用实践打动面试官

  • 场景驱动学习
    还原真实面试场景,
    帮你学会“怎么说服面试官”。

  • 三周后,面对面试官,你能自信说出:
    *“问吧,准备好了。”

最动人的作品,为自己而写,刚刚好打动别人

 1️⃣ 如果有更多疑问,联系小王,一起交流,进步

个人联系方式

2️⃣  关注公众号:后端开发成长指南(回复"面经"获取)获取过去我全部面试录音和面试复盘。

抬头看天:走暗路、耕瘦田、进窄门、见微光

  • 不要给自己这样假设:别人完成就等着自己完成了,大家都在一个集团,一个公司,分工不同,不,这个懒惰表现,这个逃避问题表现。
  • 别人不这么假设,至少本月绩效上不会写成自己的,至少晋升不是你,裁员淘汰就是你。
  • 目标:在跨越最后一道坎,拿百万年薪,进大厂。