簡體   English   中英

AMD64陣列中的AMD64未對准:為什么沒有性能下降?

[英]AMD64 misalignment of array in C: why no performance degradation?

我試圖通過在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);
}

我有以下問題:

  1. 程序中的數組訪問是否真的未對齊?
  2. 我是否考慮過可能影響該計划績效的主要因素?
  3. 是否有可能,ALIGNMENT_OFFSET為0和1的性能是相同的,因為我的CPU執行了一些“魔法”?

根據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                                                              ▒

因此,您沒有看到不良對齊的影響。

程序中的數組訪問是否真的未對齊?

是的,如果sizeof(DATATYPE)大於1,則它們是。

我是否考慮過可能影響該計划績效的主要因素?

不,你沒有。 例如,100次迭代就沒有了。 編寫一個包含1億次迭代的循環,您將獲得更逼真的結果。 沒關系,我誤讀了代碼。 到目前為止,基准看起來“很好”(除了UB),但仍有其他因素需要考慮。

是否有可能ALIGNMENT_OFFSET為0和1的性能相同

一切皆有可能,因為您的程序會調用未定義的行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM