PGO 与 LTO:profile-guided 与链接时优化

编译器 编译过程 compiling 动态链接库 Linking 接口ABI LTO PGO inline bazel增量编译 编译器有能力让不同 target 的 cpp 文件的不同编译选项,有区分地生效。但无法控制其它cpp文件对头文件的使用,因此头文件为主体的开源项目,经常不得不很小心地去处理各种使用情况。 阅读详情

单个 .cpp 编译成 .o 时,编译器只能看到这一个文件里的代码;另一个 .cpp 里的 square 函数体,对它来说是不存在的。所以只能生成一条 call square,把优化留到运行期碰运气。-flto 和 PGO 就是来解决「编译器看不到全局」这个根本限制的两种武器。这篇把它们的机制、实测和代价讲清楚。

1. 引子:编译单元边界,让优化止步于 .o

C++ 的编译模型是「一个 .cpp 一个翻译单元(translation unit)」,各自独立编译成目标文件,最后链接。这个模型带来的直接后果是:

 无 LTO 的传统编译
 ═══════════════════════════════════════════════════════════════
 main.cpp ──▶ main.o  (编译器只看得见 main.cpp,看不见 util.cpp)
 util.cpp ──▶ util.o
                 └──▶ 链接器把两个 .o 拼起来 ──▶ 可执行文件
                       链接器不做事后优化,square 只能是一次 call
 ═══════════════════════════════════════════════════════════════

main.cpp 里调用了 util.cpp 定义的 square(x),但编译 main.cpp 时编译器根本不知道 square 的实现,无法把它内联进来。用 __attribute__((noinline)) 可以复现这种「看不到函数体」的效果:

#include <cstdio>

// noinline:强制不内联,模拟「函数体在另一个编译单元、编译器看不到」
__attribute__((noinline)) int add_one(int x) { return x + 1; }

int main() {
    long r = 0;
    constexpr int n = 1000;
    for (int i = 0; i < n; ++i) {
        r += add_one(i);   // 每次迭代都要 call add_one
    }
    std::printf("r = %ld\n", r);
}
r = 500500

汇编上,call add_one 这条指令就是「跨 TU 无法内联」的具象。对比一下内联版(godbolt,gcc 13.2,-O2):

use_noinline(int):          ← 看不到函数体,只能 call
.L6:
        mov     edi, edx
        add     edx, 1
        call    square_noinline(int)   ← 每次迭代一次函数调用
        add     ecx, eax
        cmp     esi, edx
        jne     .L6

use_inline(int):            ← 函数体可见,直接内联
.L11:
        mov     ecx, eax
        imul    ecx, eax              ← 内联:乘法直接展开,无 call
        add     eax, 1
        add     edx, ecx
        cmp     edi, eax
        jne     .L11

call 的代价不只是跳转本身,还阻断了寄存器分配、常量传播等一系列后续优化。LTO 要做的,就是把这个「看不到」的边界在链接期拆掉。

官方文档:翻译阶段(translation phases)——第 8 阶段「每个翻译单元独立编译」,就是这条边界的由来。

2. LTO:把优化推迟到链接期

-flto 让编译器不直接产出机器码,而是把**中间表示(IR,GIMPLE)**存进 .o;链接时再把这些 IR 合并,做一次全局优化。于是跨 TU 的内联、常量传播、死代码消除都成为可能:

 有 LTO 的编译
 ═══════════════════════════════════════════════════════════════
 main.cpp ──▶ main.o(内含 GIMPLE IR,不是最终机器码)
 util.cpp ──▶ util.o(内含 GIMPLE IR)
                 └──▶ 链接器 + LTO 插件:合并 IR,全局优化 ──▶ 可执行文件
                       square 被跨 TU 内联,call 消失
 ═══════════════════════════════════════════════════════════════

下面是实测:一个「main.cpp 调 util.cpp 的 square」的两文件工程,CMake 加 -flto,在 Compiler Explorer 的 CMake 端点上真构建:

# CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(lto_demo LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(demo main.cpp util.cpp)
target_compile_options(demo PRIVATE -flto)   # 编译期产出 IR
target_link_options(demo PRIVATE -flto)      # 链接期做全局优化
[ 33%] Building CXX object CMakeFiles/demo.dir/main.cpp.o
[ 66%] Building CXX object CMakeFiles/demo.dir/util.cpp.o
[100%] Linking CXX executable demo
===== 程序输出开始 =====
square(9) = 81
===== 程序输出结束 =====
[100%] Built target demo

构建成功、程序正确输出 square(9) = 81。这坐实了「LTO 至少能编能跑」。真正的收益在汇编里:无 LTO 时 square 是 call,有 LTO 时它被内联进 main,call 消失。

官方文档:GCC Optimize Options(-flto)——-flto 的实现与代价(编译更慢、内存更高、产物更难调试)。

官方文档:CMake INTERPROCEDURAL_OPTIMIZATION——CMake 里更省心的写法是 set_property(TARGET demo PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE),它帮你同时加编译期和链接期 -flto。

3. PGO:先跑一遍,用真实热点重新编译

LTO 解决「看不到代码」,PGO 解决「不知道哪里热」。静态编译器只能猜哪个分支常走,而 PGO 用真实运行数据来告诉它。流程分三步:

 PGO 三段式
 ═══════════════════════════════════════════════════════════════
 ① 插桩编译   -fprofile-generate   (在代码里埋计数器)
 ② 跑代表性负载  ./app               (生成 .gcda,记录分支/调用频率)
 ③ 用 profile 重新编译  -fprofile-use  (按真实热点优化)
 ═══════════════════════════════════════════════════════════════

目标程序长这样(冷热分支分明,是 PGO 的典型优化对象):

#include <cstdio>

int main() {
    long hot = 0;
    long cold = 0;
    constexpr int n = 100000;
    for (int i = 0; i < n; ++i) {
        if (i % 1000 == 0) {
            ++cold;      // 冷路径:每 1000 次才一次
        } else {
            ++hot;       // 热路径:99.9% 都走这里
        }
    }
    std::printf("hot = %ld, cold = %ld\n", hot, cold);
}
hot = 99900, cold = 100

对应的三步命令(用法示例):

# ① 插桩编译:程序里埋好计数器
g++ -O2 -fprofile-generate app.cpp -o app
# ② 用代表性数据跑一遍,生成 .gcda 文件(记录真实频率)
./app
# ③ 用收集到的 profile 重新编译:按真实热点做布局/内联/分支优化
g++ -O2 -fprofile-use app.cpp -o app

实测补充:PGO 的完整闭环这篇已经跑通——在线沙箱的 CMake 工程里,用 execute_process 手动执行「插桩编译 → 运行 → 用 .gcda 重编译」三步。真实结果:第一步生成 /app/build/app-pgo.gcda(180 字节的 profile 数据),第三步 -fprofile-use 编译没有任何 -Wmissing-profile 警告(说明 profile 确实被读到了),两阶段运行输出都是 acc=3500。

一个关键坑要记牢:gcda 文件名 = <输出二进制名>-pgo.gcda,所以两阶段编译必须用同一个 -o 名。如果第一阶段 -o app 生成 app-pgo.gcda、第二阶段却 -o app2 去找 app2-pgo.gcda,就会报 -Wmissing-profile(profile 没被用上),看似跑通了、实际白跑。

PGO 能做的优化:把热路径的函数内联进来、把冷分支挪到远离热路径的位置(改善指令缓存)、对间接调用做 devirtualization。它的前提是「跑的那一遍负载有代表性」——拿 A/B 测试流量训练出来的 profile,拿去优化 C 场景,可能反而更糟。

官方文档:GCC Instrumentation Options(-fprofile-*)——-fprofile-generate / -fprofile-use 的完整说明。

4. LTO 与 PGO 怎么配合,代价是什么

两者是正交的:LTO 决定「优化时能看见多少代码」,PGO 决定「按什么倾向优化」。配合使用(-flto -fprofile-generate → 跑 → -flto -fprofile-use)能拿到 1+1>2 的效果,但代价也叠加:

手段解决什么代价适用
LTO(-flto)跨 TU 看不到函数体编译慢、链接期内存高、增量构建变弱发布构建、跨模块库
PGO不知道真实热点要维护 profile 数据、负载要代表性长期稳定运行的服务
两者配合全局 + 按热点双重代价,构建流程最复杂性能敏感的核心服务

关键结论:LTO 和 PGO 都不是「开了就一定更快」的免费午餐。它们改变的是编译器的「信息量」,收益取决于代码里到底有多少「跨 TU 的小函数调用」和「可预测的热点分支」。没有这些场景,开了只会让构建更慢。

5. 完整示例:一个同时受益于 LTO 和 PGO 的程序

#include <cstdio>

// 跨 TU 的小函数(真实工程里这个函数体在另一个 .cpp,LTO 才能内联它)
__attribute__((noinline)) int classify(int x) {
    return (x % 1000 == 0) ? 1 : 0;   // 冷热分支(PGO 会按真实频率优化)
}

int main() {
    long hot = 0, cold = 0;
    constexpr int n = 100000;
    for (int i = 0; i < n; ++i) {
        if (classify(i) == 1) ++cold; else ++hot;
    }
    std::printf("hot=%ld cold=%ld\n", hot, cold);
}
hot=99900 cold=100

这个程序同时踩中两个优化点:classify 是「跨 TU 的小函数」(LTO 想内联掉它的 call),里面的 x % 1000 == 0 是「99.9% 走假」的冷热分支(PGO 想把真分支挪到冷区)。生产环境里,main.cpp 和 util.cpp 分属两个翻译单元,只有 -flto 才能让 classify 跨进来,只有 PGO 才知道它几乎永远返回 0。

6. 延伸阅读

本知识库内的相关篇目:

7. 一句话总结

LTO 用 -flto 把 IR 留到链接期做全局优化、拆掉编译单元边界(跨 TU 内联让 call 变成 imul,这篇已用 CMake 工程真构建验证);PGO 用 -fprofile-generate 插桩、跑代表性负载生成 .gcda、再 -fprofile-use 按真实热点重编(沙箱受限、这篇讲流程为主)。两者正交、可叠加,但都是「用构建时间换信息量」——没有跨 TU 小函数和可预测热点,开了也白开。

UE4性能优化:PGO与LTO编译器级优化实战指南 在游戏开发与高性能计算领域,编译器优化是提升程序执行效率的关键技术。其核心原理在于,编译器在生成机器码时,通过静态分析与动态反馈,对代码进行重组与精简,从而减少指令开销、改善CPU缓存命中率。这项技术的核心价值在于,它能在不修改源代码逻辑的前提下,显著提升程序的运行时性能,尤其适用于对帧率要求苛刻的游戏、移动端应用等场景。其中,链接时优化(LTO)通过全局视角整合多个编译单元,实现跨模块的内联与死代码消除;而配置文件引导优化(PGO)则通过采集程序实际运行的“热点”数据,指导编译器进行精准的内联、向量化与分 阅读详情

相关推荐

字节跳动 Service Mesh 数据面编译优化实践,2024字节跳动Android面试真题解析

程序运行期采集到的 profile 数据中,记录了该程序的热点函数及指令,这里不做过多展开,以两个简单例子说明它是如何指导编译器做 PGO 优化的。

2401_83977580的博客 757

gcc-for-openEuler性能优化指南:提升编译效率的7个技巧

前往项目官网免费下载:[https://ar.openeuler.org/ar/](https://ar.openeuler.org/ar/?utm_source=csdn_blog) 想要在openEuler系统上获得极致的编译性能吗?gcc-for-openEuler作为专为openEuler优化的GCC编译器套件,提供了强大的编译优化能力。本文将为您揭示7个提升编译效率的关键技巧,帮助您充

gitblog_06890的博客 173

Labview程序框架介绍

当掌握LabVIEW基础知识并达到,理解单个小型模块程序会相对轻松。而若想进一步探索大型程序,就必然需要了解程序框架相关内容。LabVIEW常用的程序架构包括等。在多年工作中,我接触过的众多高级工程师所开发的大型程序,基本都基于这些架构搭建。接下来,将为大家详细介绍这些框架。

Misterlhw的博客 4617

使用GCC的PGO(Profile-guided Optimization)优化整个系统

启发来自于巨硬在自家服务器上做的实验,废话不多直接上图微软的方法微软的方法可以看到使用PGO优化的内核还是有一些性能提升的零、前提想要使用PGO编译优化,你的gcc编译器需要开启支持pgo特性,gentoo系统如下 一、内核kernel的优化 然后在新内核下运行系统一段时间,打开各种软件如浏览器、mpv播放器、cmus、办公、编译软件、下载、游戏、steam等等(即将日常用系统的各个软件和场景全部跑一遍),以让内核收集足够全面的profile数据(gcov数据)#注:开启了CONFIG_DEBUG_

天涯路的专栏 6640

你需要这样一个Ros软路由—— 路由器+外网+一号通ip线路=动态ip的WiFi信号

功能强大 管理便捷—给您全新的路由体验 一键更换指定线路or批量更换所有IP/MAC/SSID 自定义走本地网络策略的分流功能 设备批发价、不限制拨号账号服务商 强大的单设备/多设备IP去重功能 批量导入、管理一号通线路 一键任意切换5G_WiFi(推荐)/2.4G_WiFi(建议不用) 设备支持PPTP/L2TP/SSTP/openVP.N等协议 独家支持openVPN,适用于网络受限用户 支持自行接入AP和交换机扩容 一键打开/关闭所有虚拟WiFi 一键隐藏/显示设备WiFi...

米粒儿 4249

OpenWRT二级路由DHCP客户端配置:实现IPv4 WAN自动获取与网段隔离

本文详细讲解了如何将OpenWRT配置为二级路由器,重点在于设置其WAN口为DHCP客户端以自动获取IPv4地址,并修改LAN口网段实现与上级网络的隔离。文章提供了从网络拓扑规划、具体配置步骤到防火墙设置的完整指南,并分享了常见问题排查与避坑经验,帮助用户构建稳定且功能独立的家庭网络环境。

weixin_29268267的博客 293

Rust 中的 Profile-Guided Optimization(PGO):从原理到深度实践

Rust中的Profile-Guided Optimization(PGO)通过运行时数据指导编译器优化,能显著提升性能。其核心流程包括插桩构建、数据收集和优化重编译三阶段。实践案例显示,PGO可优化内联决策、分支预测和代码布局,如在HTTP服务器中对高频调用的函数进行针对性优化。关键要点是确保训练数据真实反映生产环境流量,避免反向优化,并建议定期更新profile数据。结合LTO使用可获得额外5-10%性能提升。最佳实践包括集成到CI/CD流程、使用生产流量训练和量化优化效果,特别适合性能敏感的服务端应用

2501_94043283的博客 1250

PostgreSQL中idle in transaction状态的5个隐藏危害及实战解决方案

本文深入剖析了PostgreSQL中`idle in transaction`连接状态的五大隐藏危害,包括内存与锁泄漏、VACUUM受阻导致表膨胀、事务ID加速消耗、连接池资源耗尽以及增加故障排查复杂度。文章提供了基于`pg_stat_activity`视图的监控方法、识别高危事务的SQL脚本,并给出了从数据库参数调优(如设置`idle_in_transaction_session_timeout`)到应用层编码规范与连接池配置的完整实战解决方案。

zzz56的博客 234

Rust 中的 Profile-Guided Optimization (PGO) 深度实践

Profile-Guided Optimization (PGO) 是一种基于运行时数据的编译优化技术。与传统的静态优化不同,PGO 通过收集程序实际运行时的性能数据,指导编译器做出更精准的优化决策。在 Rust 生态中,PGO 能够显著提升关键路径的性能,特别是在处理复杂分支预测、函数内联和代码布局优化方面表现出色。

xiaomo0007的博客 831

OpenVox 8FXO板卡驱动安装记录

OpenVox A800P和A1200P的板卡驱动安装及问题解决方法

clliu的专栏 2463

使用 Python 获取网络数据

本文介绍了 Python 获取网络数据、使用 requests 库、编写爬虫代码以及使用 IP 代理的方法。Python 的 requests 库非常方便,可以帮助我们快速访问网络资源。编写爬虫程序需要掌握正则表达式、HTTP 协议等知识,同时需要注意爬取速度和频率,以避免对被爬取网站造成负担。最后,使用 IP 代理可以帮助我们隐匿身份,保护我们的网络安全。

互联说 2695

LDC高级特性详解:从profile-guided优化到链接时优化(LTO)全攻略

LDC作为基于LLVM的D语言编译器,提供了强大的优化能力,其中profile-guided优化(PGO)和链接时优化(LTO)是提升程序性能的关键技术。本文将详细介绍这两项高级特性的工作原理、使用方法及最佳实践,帮助开发者充分发挥LDC编译器的性能潜力。 ## 什么是链接时优化(LTO)? 链接时优化(LTO)是一种跨模块的优化技术,它允许编译器在链接阶段对整个程序进行分析和优化,而不仅仅是

gitblog_00246的博客 360

PINNACLE:PINN自适应配点与实验点选择算法

PINNACLE算法通过引入动态权重机制,实现了PINN训练点选择的自适应优化。该算法基于对训练过程中不同区域学习需求变化的深入理解,设计了平滑过渡的权重函数,确保了模型在不同训练阶段能够优先学习最需要的区域。理论分析和实验结果均表明,PINNACLE不仅能够保证收敛性,而且能够显著提高PINN的性能。这一算法为物理信息神经网络的应用提供了重要支持,尤其适用于复杂PDE问题的求解。

VectorShift的博客 1136

Rust Profile-Guided Optimization(PGO):数据驱动的极致性能优化

摘要 Profile-Guided Optimization (PGO) 是一种基于运行时性能数据指导编译优化的技术,通过收集程序实际执行特征(如热点代码路径、分支频率等)实现10-30%的性能提升。Rust通过LLVM支持完整的PGO流程:1) 插桩编译插入性能计数器;2) 运行代表性工作负载生成.profraw文件;3) 使用配置文件重新编译优化代码布局、分支预测等。关键挑战在于选择真实反映生产环境的工作负载,并处理LLVM版本兼容性问题。实践表明,PGO特别适合长期运行的性能敏感型应用(如数据库、编译

超哥的博客 894

指纹浏览器降维打击(下):Cloudflare Turnstile 与 hCaptcha 的底层交互逻辑

本文将深度拆解:Turnstile 与 hCaptcha 的 Iframe 沙箱通信机制,动态混淆 JS 与 PoW(工作量证明)的物理破解法则,以及如何通过 C++ 底层事件合成与环境基因强绑定,实现验证码的“无感过验”。

数据知道的博客 415

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Rust Profile-Guided Optimization 实践

PGO 是 Rust 性能优化中一项“低频但高效”的武器。长生命周期、性能关键的后端服务;数据规模和访问模式稳定的计算任务;对启动时间或 CPU 占用率有严格要求的程序。采样阶段的运行场景要尽量接近真实负载,否则优化方向可能偏离;对快速迭代的项目,PGO 的维护成本较高;并非所有程序都能从 PGO 中获益,I/O 密集型应用效果有限。一句话总结:PGO 让编译器“用数据指导优化”,是 Rust 性能调优中真正让“编译器变聪明”的一步。

weixin_43752269的博客 877

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

突破Python性能瓶颈:PGO与LTO编译优化实战指南

你是否曾为Python程序的执行速度烦恼?当数据处理遇到性能瓶颈,或Web服务响应迟缓时,除了代码层面的优化,编译级优化可能带来意想不到的提速效果。本文将带你深入CPython的编译优化世界,通过**PGO(Profile-Guided Optimization,基于轮廓的优化)** 和**LTO(Link-Time Optimization,链接时优化)** 技术,实现平均15-30%的性能提升...

gitblog_00476的博客 558

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Mesen PGO 优化构建全流程:从准备采样 ROM 到产出高性能模拟器二进制

本文以 Mesen 仓库中 `PGOHelper/PGOGames` 目录及其说明文档为主线,完整讲解 Mesen 基于 Profile-Guided Optimization(PGO,性能引导优化)的构建工作流:如何准备采样用 ROM、插桩二进制如何自动运行游戏采集运行特征、`make pgo` 背后脚本如何完成「插桩 → 采样 → 合并 profile → 重新优化编译」的闭环。读完本文,你将

gitblog_00995的博客 725

Gonka网关内部揭秘:devshard如何用链上托管实现逐请求计费(完整入门指南)

本文带你拆解 Gonka 开源项目中的 devshard 网关:它如何以 OpenAI 兼容接口接入 AI 推理,把每笔请求的算力费用锁定在区块链托管账户(escrow)中,按 nonce 与 token 逐请求计费,并在链上完成结算与退款。无需任何区块链背景,10 分钟看懂整条计费链路。 ## 🎯 devshard 解决什么问题? 传统 AI 网关的计费由中心化平台"自说自话":它既是商家

gitblog_00328的博客 383

如何用GCC LTO + Profile-guided Optimization裁剪80%冗余代码?

掌握嵌入式系统C++代码精简之道,通过GCC LTO与Profile-guided Optimization实现80%冗余代码裁剪。适用于资源受限场景,提升性能与效率。2025全球C++及系统软件技术大会:嵌入式系统C++代码裁剪实践专题分享实战经验,值得收藏。

BreakNexus的博客 1094

为什么顶级嵌入式团队已全面转向GCC 14?揭秘其对LTO和链接时优化的突破支持

掌握GCC 14特性支持,提升嵌入式开发效率。详解其对LTO和链接时优化的突破性支持,适用于高性能固件构建与资源受限场景,显著优化代码体积与执行速度。编译器升级关键指南,值得收藏。

QuickProceed的博客 717

Rust 中的 Profile-Guided Optimization (PGO) 实践与深度解析

与传统的静态优化不同,PGO 通过收集程序实际运行时的性能数据,指导编译器做出更精准的优化决策。在 Rust 生态中,PGO 能够显著提升程序性能,特别是对于热点路径密集的应用场景。关键优化点在于:解析器的热点路径集中在字符串和数字解析上,PGO 使编译器将这些代码段紧密排列,提高了 CPU 缓存命中率。对于 Rust 项目,结合 LTO(链接时优化)和 PGO 可以获得最佳效果,但需要注意编译时间的显著增加。1. 精准的分支预测:将高频执行的分支放在更优的代码路径上,减少 CPU 流水线停顿。

didididididi007的博客 470

深入 Rust 编译的心脏:从 `profile` 配置到 PGO 的性能榨取艺术

永远从测量开始 (Benchmark):不要盲目使用 `lo = “fat”。使用cargo bench` 和来验证你的改动。理解你的目标:你是要最小的二进制文件(, `panic = “abort”),最快的运行时(, PGO),还是最快的 CI 编译(使用自定义 Profile:不要只依赖dev和release。为你的 CI、基准测试、生产环境创建不同的profile。Rust 给了我们控制编译器的强大能力,而精通这些配置,就是从“写出能跑的代码”到“写出极致性能代码”的必经之路。

易辰的博客 1050

Upscuits 自定义样式:图标告警配色随心换

你的监控页还是绿/红/黄三件套 🙃?想换成自己的品牌色?Upscuits 的样式定制入口全在源码目录里,改两个 LESS 文件、编译一次就生效。 ## 动手前先确认三件事 - 改的是 source/less/ 下的源文件,不是 `public/css/` 里的编译产物——编译会覆盖它,直接改等于白改。 - LESS 编译链可用:`grunt less` 能跑通,后面全靠它把源码变成 CSS。

gitblog_00288的博客 576

第 10 讲 · PGO 实战:让程序的真实运行数据指导编译

第 9 讲的所有选项都是"静态"的——编译器看着代码猜哪里是热点、哪个分支走得多、循环一般跑多少次。

liferecords的博客 193

Electron 专属 PGO Profile 生成体系深度解析:为发布构建定制 Profile-Guided Optimization 数据

PGO(Profile-Guided Optimization,profile 引导优化)是 Electron 发布构建获得额外性能的关键手段。本篇基于 Electron 仓库 [script/pgo](https://link.gitcode.com/i/4ede41dac556b4e6c78dba88c5801636) 的完整基础设施,系统讲解 Electron 为何不能直接复用 Chromi

gitblog_01006的博客 508
上一篇: gdb 实战:断点、watchpoint、core dump 与多线程调试
下一篇: clang-tidy 与 cppcheck:静态分析落地
无名猿
博客等级 码龄10年 61粉丝 184原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值