gpt4 book ai didi

assembly - x86-64 做地址计算 mov 即 mov i(r, r, i), r 在端口 1 上执行?还是还是p0156?

转载 作者:行者123 更新时间:2023-12-04 08:53:29 26 4
gpt4 key购买 nike

我在问 mov需要计算该地址的指令,即(在 at&t 语法中mov i(r, r, i), regmov reg, i(r, reg, i)必须在端口 1 上执行,因为它们实际上是带有 3 个操作数 + MOV 的 LEA,或者它们可以在端口 0156 上自由执行。
如果他们确实在端口 1 上执行了 LEA 部分,那么一旦地址计算完成,端口 1 是否会被解除阻塞,或者是否需要首先完成整个内存加载。
在 ICL 上似乎 p7 可以做索引地址模式?

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


#define BENCH_ATTR __attribute__((noinline, noclone, aligned(4096)))


#define TERMS 3

void BENCH_ATTR
test_store_port() {
const uint32_t N = (1 << 29);

uint64_t dst, loop_cnt;
uint64_t src[16] __attribute__((aligned(64)));

asm volatile(
"movl %[N], %k[loop_cnt]\n\t"
".p2align 5\n\t"
"1:\n\t"

"movl %k[loop_cnt], %k[dst]\n\t"
"andl $15, %k[dst]\n\t"
#if TERMS == 3
"movl %k[dst], (%[src], %[dst], 4)\n\t"
#else
"movl %k[dst], (%[src])\n\t"
#endif


"decl %k[loop_cnt]\n\t"
"jnz 1b\n\t"
: [ dst ] "+r"(dst), [ loop_cnt ] "+r"(loop_cnt)
: [ N ] "i"(N), [ src ] "r"(src), "m"(*((const uint32_t(*)[16])src))
: "cc");
}

int
main(int argc, char ** argv) {
test_store_port();
}
结果与 #define TERMS 3 :
perf stat -e uops_dispatched.port_2_3 -e uops_dispatched.port_7_8 -e uops_issued.any -e cpu-cycles ./bsf_dep

Performance counter stats for './bsf_dep':

297,191 uops_dispatched.port_2_3
537,039,830 uops_dispatched.port_7_8
2,149,098,661 uops_issued.any
761,661,276 cpu-cycles

0.210463841 seconds time elapsed

0.210366000 seconds user
0.000000000 seconds sys
结果与 #define TERMS 1 :
perf stat -e uops_dispatched.port_2_3 -e uops_dispatched.port_7_8 -e uops_issued.any -e cpu-cycles ./bsf_dep

Performance counter stats for './bsf_dep':

291,370 uops_dispatched.port_2_3
537,040,822 uops_dispatched.port_7_8
2,148,947,408 uops_issued.any
761,476,510 cpu-cycles

0.202235307 seconds time elapsed

0.202209000 seconds user
0.000000000 seconds sys

最佳答案

所有 CPU 都在加载或存储地址端口中的 AGU 上为加载/存储微指令生成地址,而不是在 ALU 端口上。只有 LEA 使用 ALU 执行端口进行移位和加法运算。
如果复杂的寻址模式需要端口 1,https://uops.info/和/或 https://agner.org/optimize/会在他们的指令表中这么说。但他们不需要:加载只需要 p23,并且只存储 p237 用于存储地址 + p4 用于存储数据。

实际上只是 p23 用于索引商店;端口 7 上的简单存储地址 AGU(Haswell 通过 Skylake)只能处理 reg+constant,这意味着如果您在代码中使用索引寻址模式,地址生成可能会成为瓶颈,否则每个时钟可以承受 2 个负载 + 1 个存储。
(早期的 Sandybridge 家族,SnB 和 IvB,甚至会 un-laminate indexed stores,因此也有前端成本。)
冰湖改变了 ,在端口 7 和 8 上有 2 个专用存储 AGU。存储地址 uop 不能再借用负载 AGU,因此存储 AGU 必须是全功能的。 https://uops.info/html-tp/ICL/MOV_M32_R32-Measurements.html确认具有索引寻址模式的存储确实在 ICL 上以 2/时钟运行,因此两个存储 AGU 都是功能齐全的。例如mov [r14+r13*1+0x4],r8d . (uops.info 没有测试大于 1 的比例因子,但我假设两个 store-AGU 都是相同的,在这种情况下它们都会处理它。)
不幸的是,HSW/SKL 对调优不再重要还需要很多年,因为英特尔仍在销售源自 Skylake 的微架构,因此多年来它们将成为桌面软件安装基础的很大一部分。

关于assembly - x86-64 做地址计算 mov 即 mov i(r, r, i), r 在端口 1 上执行?还是还是p0156?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63975049/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com