MST

星途 面试题库

面试题:热点代码的识别与基于缓存优化的C代码改写

给定一段C代码(代码片段如下:```c #include <stdio.h> #define N 1000000 int main() { int arr[N]; for (int i = 0; i < N; i++) { arr[i] = i; } int sum = 0; for (int j = 0; j < N; j++) { sum += arr[j]; } printf("Sum: %d\n", sum); return 0; } ```),请分析其中可能的热点代码,并说明如何利用缓存优化技术对这段代码进行改写以提升性能。
33.2万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

热点代码分析

  1. 循环赋值部分
for (int i = 0; i < N; i++) {
    arr[i] = i;
}

此循环执行次数为N(一百万次),每次迭代都要访问数组arr并赋值,频繁的内存访问操作会成为性能瓶颈。 2. 循环求和部分

for (int j = 0; j < N; j++) {
    sum += arr[j];
}

同样执行N次,每次都要从内存中读取arr[j]的值进行累加,大量的内存读取操作也会影响性能。

缓存优化技术改写

  1. 分块优化: 将数组访问按照缓存行大小进行分块,以减少缓存缺失。假设缓存行大小为CACHE_LINE_SIZE(实际应用中需根据硬件确定),可改写如下:
#include <stdio.h>
#define N 1000000
#define CACHE_LINE_SIZE 64
// 假设每个int占4字节,每个缓存行可容纳16个int
#define BLOCK_SIZE (CACHE_LINE_SIZE / sizeof(int))

int main() {
    int arr[N];
    // 分块赋值
    for (int i = 0; i < N; i += BLOCK_SIZE) {
        for (int k = 0; k < BLOCK_SIZE && i + k < N; k++) {
            arr[i + k] = i + k;
        }
    }
    int sum = 0;
    // 分块求和
    for (int j = 0; j < N; j += BLOCK_SIZE) {
        for (int k = 0; k < BLOCK_SIZE && j + k < N; k++) {
            sum += arr[j + k];
        }
    }
    printf("Sum: %d\n", sum);
    return 0;
}
  1. 循环合并: 如果可能,将两个循环合并为一个,减少循环控制开销以及内存访问的不连续性。
#include <stdio.h>
#define N 1000000

int main() {
    int arr[N];
    int sum = 0;
    for (int i = 0; i < N; i++) {
        arr[i] = i;
        sum += arr[i];
    }
    printf("Sum: %d\n", sum);
    return 0;
}

这种方式减少了对数组arr的重复遍历,提升了缓存利用率,从而提升性能。但如果在赋值和求和之间有其他逻辑操作,此方法可能不适用。