组装功能中用于将缓冲区设置为零的不一致时钟周期测量

Inconsistent Clock Cycles Measurement in Assembly Function for Setting Buffer to Zero

提问人:Z123 提问时间:6/8/2023 最后编辑:Sep RolandZ123 更新时间:6/10/2023 访问量:32

问:

我目前正在研究一个将缓冲区设置为零的汇编函数。我正在测量执行该函数所需的时钟周期。但是,我遇到了一个问题,即无论缓冲区大小如何增加,时钟周期数都保持不变,我无法解释此行为。

这是我正在使用的汇编函数:

_set0:
set0:
    movq    $0, (%rdi)
    movq    $0, 8(%rdi)
    movq    $0, 16(%rdi)
    movq    $0, 24(%rdi)
    movq    $0, 32(%rdi)
    movq    $0, 40(%rdi)
    ret

我预计,随着指令数量的增加(表示缓冲区大小),执行该函数所需的时钟周期数将成比例增加。但是,当我按如下方式修改函数时:movq

_set0:
set0:
    movq    $0, (%rdi)
    movq    $0, 8(%rdi)
    movq    $0, 16(%rdi)
    movq    $0, 24(%rdi)
    movq    $0, 32(%rdi)
    movq    $0, 40(%rdi)
    movq    $0, 48(%rdi)
    movq    $0, 56(%rdi)
    movq    $0, 64(%rdi)
    movq    $0, 72(%rdi)
    movq    $0, 80(%rdi)
    movq    $0, 88(%rdi)
    ret

尽管缓冲区大小增加,但测量的时钟周期数保持不变。

我将不胜感激任何关于为什么时钟周期测量没有像预期的那样随着缓冲区大小而增加的任何见解或建议。

为了测量时钟周期,我从 C 文件调用此函数,我有这个:

static inline uint64_t cpucycles(void) {
    uint64_t result;

    __asm__ volatile("rdtsc; shlq $32,%%rdx; orq %%rdx,%%rax" : "=a"(result) : : "%rdx");

    return result;
}

然后我取中位数,如下所示:

static uint64_t cpucycles_median(uint64_t *cycles, size_t timings) {
    for (size_t i = 0; i < timings - 1; i++) {
        cycles[i] = cycles[i + 1] - cycles[i];
    }

    return median(cycles, timings - 1);
}

为了计算运行该函数所需的周期数,我运行了该函数 1000 次,并取每次运行所花费的周期的中位数。

程序集 x86-64 微基准测试

评论


答: 暂无答案