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)
我有以下问题:
根据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)
因此,您没有看到不良对齐的影响.