C++大厂面试真题宝典 精选100道
·
案例1:循环展开(Loop Unrolling)
问题:循环控制开销占比高
代码语言:javascript
代码运行次数:0
运行
AI代码解释
cpp// 原始代码for(int i=0; i<1024; i++) { sum += arr[i];} // 优化后(展开4次)for(int i=0; i<1024; i+=4) { sum += arr[i] + arr[i+1] + arr[i+2] + arr[i+3];}
汇编视角:
- 原始代码:
cmp,jl指令反复执行1024次 - 优化后:循环次数减少为256次,减少分支预测失败概率
案例2:分支预测优化
问题:条件分支导致流水线停滞
代码语言:javascript
代码运行次数:0
运行
AI代码解释
cpp// 原始代码(分支密集)if (x < 0) { x = -x;} // 优化后(无分支版本)x = x < 0 ? -x : x;
汇编视角:
- 原始代码:
test,jge指令可能导致预测错误 - 优化后:使用
CMOV指令(条件移动)消除分支
案例3:内存访问对齐
问题:非对齐内存访问导致性能下降
代码语言:javascript
代码运行次数:0
运行
AI代码解释
cpp// 原始代码(未对齐)float* arr = (float*)malloc(N*sizeof(float)+1); // 故意不对齐 // 优化后alignas(64) float arr[N]; // 使用C++11对齐属性
汇编视角:
- 原始代码:
movups(非对齐加载) - 优化后:
movaps(对齐加载,吞吐量翻倍)
案例4:SIMD指令优化
问题:标量运算未利用向量单元
代码语言:javascript
代码运行次数:0
运行
AI代码解释
cpp// 原始代码(标量计算)for(int i=0; i<N; i++) { a[i] = b[i] * c[i];} // 优化后(AVX2向量化)#include <immintrin.h>__m256 *a_vec = (__m256*)a;__m256 *b_vec = (__m256*)b;__m256 *c_vec = (__m256*)c;for(int i=0; i<N/8; i++) { a_vec[i] = _mm256_mul_ps(b_vec[i], c_vec[i]);}
汇编视角:
- 原始代码:
vmulss(单精度标量乘) - 优化后:
vmulps(单指令8路并行乘)
案例5:消除假共享(False Sharing)
问题:多线程竞争同一缓存行
代码语言:javascript
代码运行次数:0
运行
AI代码解释
cpp// 原始代码(结构体紧凑布局)struct Data { int a; int b;} data[8]; // 优化后(添加填充)struct alignas(64) PaddedData { int a; char padding[60]; // 填充至64字节 int b;};PaddedData data[8];
汇编视角:
- 原始代码:多个线程频繁触发
MOVNTDQA(非临时读取) - 优化后:每个线程操作独立缓存行,减少
MESI协议开销
案例6:内联函数优化
问题:函数调用开销显著
代码语言:javascript
代码运行次数:0
运行
AI代码解释
cpp// 原始代码inline int add(int a, int b) { return a+b; } // 优化后(强制内联)__attribute__((always_inline)) inline int add(int a, int b) { return a+b;}
汇编视角:
- 原始代码:
call add指令 - 优化后:直接内联为
add指令,消除调用栈开销
案例7:移动语义优化
问题:临时对象拷贝开销
代码语言:javascript
代码运行次数:0
运行
AI代码解释
cpp// 原始代码std::vector<std::string> v;v.push_back(std::string("hello")); // 触发拷贝 // 优化后v.emplace_back("hello"); // 直接构造
汇编视角:
- 原始代码:
movaps拷贝内存 - 优化后:
lea直接计算地址,无拷贝操作
案例8:避免动态分配
问题:频繁new/delete导致内存碎片
代码语言:javascript
代码运行次数:0
运行
AI代码解释
cpp// 原始代码for(auto& obj : objects) { obj = std::make_unique<Data>();} // 优化后(对象池)std::vector<Data> pool(1024);auto& obj = pool[idx++];
汇编视角:
- 原始代码:
call operator new频繁系统调用 - 优化后:栈分配或预分配内存,无
malloc指令
案例9:消除虚函数调用
问题:虚函数表查找开销
代码语言:javascript
代码运行次数:0
运行
AI代码解释
cpp// 原始代码class Shape { virtual void draw()=0; }; // 优化后(CRTP模式)template<typename Derived>class Shape {public: void draw() { static_cast<Derived*>(this)->draw_impl(); }};
汇编视角:
- 原始代码:通过虚表指针
mov rax, [rdi]查找函数地址 - 优化后:直接调用
call目标函数,无间接跳转
案例10:循环交换(Loop Interchange)
问题:内存访问不连续
代码语言:javascript
代码运行次数:0
运行
AI代码解释
cpp// 原始代码(行优先访问)for(int i=0; i<N; i++) { for(int j=0; j<M; j++) { arr[i][j] = ...; // 列访问不连续 }} // 优化后(列优先访问)for(int j=0; j<M; j++) { for(int i=0; i<N; i++) { arr[i][j] = ...; // 行访问连续 }}
汇编视角:
- 原始代码:
mov eax, [rsi+rdx*4]步长不固定 - 优化后:连续内存访问,利用
prefetcht0预取
案例11:避免类型转换
问题:隐式类型转换开销
代码语言:javascript
代码运行次数:0
运行
AI代码解释
cpp// 原始代码double sum = 0.0;for(int i=0; i<N; i++) { sum += arr[i]; // int到double隐式转换} // 优化后double sum = 0.0;for(int i=0; i<N; i++) { sum += static_cast<double>(arr[i]); // 显式转换}
汇编视角:
- 原始代码:
cvtsi2sd隐式转换指令 - 优化后:编译器可能优化为
vmovsd直接加载
案例12:编译器优化选项
问题:未充分利用编译器优化
代码语言:javascript
代码运行次数:0
运行
AI代码解释
bash# 原始编译g++ -O0 code.cpp # 优化后g++ -O3 -march=native code.cpp
汇编视角:
-O0:包含调试信息,无优化-O3:启用循环展开、内联、向量化等高级优化-march=native:生成针对当前CPU的SIMD指令(如AVX-512)
核心优化原则
- 减少分支:降低分支预测失败率
- 提升局部性:利用CPU缓存(时间/空间局部性)
- 向量化:充分利用SIMD指令集
- 减少内存操作:避免缓存失效和页面错误
- 消除冗余:减少重复计算和临时对象
通过汇编视角分析,可以直观看到优化如何影响指令流水线、内存访问模式和CPU资源利用率,这是理解性能瓶颈的关键。
更多推荐


所有评论(0)