面试题答案
一键面试优化思路
- 循环展开:使用
#pragma unroll
指令可以提示编译器对循环进行展开,减少循环控制的开销,提高指令级并行度。 - 向量化:使用
#pragma vector
相关指令(不同编译器可能有不同具体指令,如#pragma ivdep
在GCC中可忽略循环依赖进行向量化),让编译器将循环操作向量化,利用SIMD(单指令多数据)技术并行处理多个数据。
代码示例
循环展开示例
#include <stdio.h>
// 未优化的函数
void sum_array_unoptimized(int *arr, int n, int *result) {
int i;
*result = 0;
for (i = 0; i < n; i++) {
*result += arr[i];
}
}
// 优化后的函数,使用循环展开
void sum_array_optimized(int *arr, int n, int *result) {
int i;
*result = 0;
#pragma unroll 4 // 展开因子设为4
for (i = 0; i < n; i++) {
*result += arr[i];
}
}
向量化示例(以GCC编译器为例)
#include <stdio.h>
// 未优化的函数
void multiply_array_unoptimized(int *arr1, int *arr2, int *result, int n) {
int i;
for (i = 0; i < n; i++) {
result[i] = arr1[i] * arr2[i];
}
}
// 优化后的函数,使用向量化相关指令
void multiply_array_optimized(int *arr1, int *arr2, int *result, int n) {
int i;
#pragma ivdep // 忽略循环依赖进行向量化
for (i = 0; i < n; i++) {
result[i] = arr1[i] * arr2[i];
}
}
在实际应用中,需注意不同编译器对#pragma
指令的支持情况和具体语法可能有所差异,同时,过度展开或不恰当的向量化可能导致代码体积增大、缓存命中率降低等负面影响,需要根据实际情况进行测试和调优。