我试图通过在 C 中错位数组来导致性能下降。我的机器有一个 64 字节的缓存,因此我在程序中使用了 64 字节的步长,从错位的地址开始。然而,结果与使用正确对齐的访问时保持一致。也使用多个数组没有改变任何东西。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define N 10000000
#define DATATYPE long
#define ALIGNMENT __alignof__(DATATYPE)
#define CACHE_SIZE 64
#define STEP_SIZE (CACHE_SIZE / sizeof(DATATYPE))
#define NR_ARRAYS 20
#define ALIGNMENT_OFFSET 1

DATATYPE arr[N];

DATATYPE sum(DATATYPE **ptr, int size) {
    DATATYPE sum = 0;
    int i, j;
    for (i = 0; i < size; i += STEP_SIZE) {
        for (j = 0; j < NR_ARRAYS; j++) {
            sum += ptr[j][i];
        }
    }
    return sum;
}

int main() {
    DATATYPE *arrs[20];
    int i;
    for (i = 0; i < NR_ARRAYS; i++) {
        arrs[i] = (DATATYPE*)((long) malloc(N * sizeof(DATATYPE)) + ALIGNMENT_OFFSET);
    }

    long result = 0;
    clock_t tic = clock();
    for (i = 0; i < 100; i++) {
        result += sum(arrs, N-1);
    }
    clock_t toc = clock();
    printf("result: %ld ", result);
    printf("elapsed: %f seconds\n", (double)(toc - tic) / CLOCKS_PER_SEC);
}

我有以下问题:
  • 程序中的数组访问真的没有对齐吗?
  • 我是否考虑了可能影响该程序性能的主要因素?
  • 是否有可能,由于我的 CPU 执行的某些“魔法”,ALIGNMENT_OFFSET 为 0 和 1 的性能相同?
  • 最佳答案

    根据 perf (请参阅 https://perf.wiki.kernel.org/index.php/Main_Page ),您的代码中的大部分时间都由与以下相关的循环指令(比较 + 跳转)占用:

    for (i = 0; i < size; i += STEP_SIZE)
    
    
           │    DATATYPE sum(DATATYPE **ptr, int size) {                                        ▒
           │        DATATYPE sum = 0;                                                           ▒
           │        int i, j;                                                                   ▒
           │        for (i = 0; i < size; i += STEP_SIZE) {                                     ▒
           │            for (j = 0; j < NR_ARRAYS; j++) {                                       ▒
           │                sum += ptr[j][i];                                                   ▒
      2.83 │60:   mov    (%rdx),%rdi                                                            ▒
      4.37 │      add    $0x8,%rdx                                                              ▒
      5.50 │      add    (%rdi,%r8,1),%rcx                                                      ▒
           │                                                                                    ▒
           │    DATATYPE sum(DATATYPE **ptr, int size) {                                        ▒
           │        DATATYPE sum = 0;                                                           ▒
           │        int i, j;                                                                   ▒
           │        for (i = 0; i < size; i += STEP_SIZE) {                                     ▒
           │            for (j = 0; j < NR_ARRAYS; j++) {                                       ▒
     86.29 │      cmp    %r12,%rdx                                                              ▒
           │    ↑ jne    60                                                                     ▒
      0.10 │      add    $0x40,%r8                                                              ▒
    

    因此,您看不到错误对齐的影响。

    关于c - C : why no performance degradation? 中阵列的 AMD64 错位,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21522695/

    10-11 12:20