【发布时间】:2020-01-29 00:55:24
【问题描述】:
我正在使用 FASM,这是我的程序
format ELF64
section '.text' executable
public func
func:
vmovaps ymm0, YWORD [.table]
xor rax, rax
ret
align 32
.table:
DQ 1024
DQ 1024
DQ 1024
DQ 1024
DQ 2048
DQ 2048
DQ 2048
DQ 2048
我使用 AVX,所以我创建了一个表(必须在 32 字节边界对齐) 初始化 ymm0 寄存器。 但是当我尝试编译这个程序时,我从 FASM 收到“section is notaligned enough”错误。 “.table”必须在 32 字节边界对齐,因为我使用的是“movaps”(或 movdqa(无论如何))。但为什么 FASM 给我一个错误? 像这样使用'align'有错吗?
更新 做这样的事情是否正确?因为这样做,程序运行没有任何问题,但它是正确的方式吗?
section '.text' executable
public func
func:
vmovaps ymm0, YWORD [.table]
xor rax, rax
ret
section '.rodata' align 32
.table:
DQ 1024
DQ 1024
DQ 1024
DQ 1024
DQ 2048
DQ 2048
DQ 2048
DQ 2048
【问题讨论】:
-
请注意,将数据放在代码旁边几乎没有什么好处。 x86 CPU 使用拆分 I/D L1 高速缓存和拆分 iTLB / dTLB。 (但统一了 L2 数据和 L2TLB)。通常最好将所有常量组合在一起,以避免数据污染 I-cache,反之亦然;这就是为什么
section .rodata是一回事。此外,对于 AVX / AVX2,您可以使用vpbroadcastq或vbroadcastsd加载,因此您只需要一个dq 1024来填充寄存器。如果您无论如何要将它们加载到寄存器中,这可以让您免费“压缩”常量,除非它不适用于vpaddq ymm0, [mem]例如 -
谢谢人...好点...
-
但是有一点......将表格放在每个函数的末尾,我们的最终文件将太大!对吗?
-
一般来说,您不想复制常量,即使它们很小。虽然我猜如果这意味着函数的所有常量都在同一个缓存行中,那么重复一个标量浮点数或双精度数是有意义的。 (而不是从常量附近的一个单独位置加载一个常量,用于另一个函数,它只共享一个小常量。)无论如何,避免重复是一个单独的问题,而不是将所有rodata 组合到一个部分中。你想两者都做。
-
@PeterCordes 对于重复使用的常量,有一个特殊的 ELF 功能可以在适当的部分合并相等的常量。
标签: assembly x86 sse memory-alignment fasm