AMD64阵列中的AMD64未对准:为什么没有性能下降?

box*_*box 3 c arrays x86-64 alignment

我试图通过在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);
}
Run Code Online (Sandbox Code Playgroud)

我有以下问题:

  1. 程序中的数组访问是否真的未对齐?
  2. 我是否考虑过可能影响该计划绩效的主要因素?
  3. 是否有可能,ALIGNMENT_OFFSET为0和1的性能是相同的,因为我的CPU执行了一些"魔法"?

hiv*_*ert 5

根据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                                                              ?
Run Code Online (Sandbox Code Playgroud)

因此,您没有看到不良对齐的影响.