我试图在Windows中测试TDM-GCC 64位汇编中的附加功能.我在前一段时间搜索了资源,我遇到了类似的代码(我做了一些修改,在TDM-GCC中编译它).
typedef struct
{
int size;
__uint64_t uints[130];
} BigInteger;
void add(BigInteger *X, BigInteger *Y); // X += Y
// %rcx holds address of X, and %rdx holds address of Y apparently.
// calc.s - assembly file
.globl add
add:
movq 8(%rdx), %rax
addq %rax, 8(%rcx)
movq 16(%rdx), %rax
adcq %rax, 16(%rcx)
movq 24(%rdx), %rax
adcq %rax, 24(%rcx)
... ...
Run Code Online (Sandbox Code Playgroud)
第一个汇编代码有效.不利的是,只要计算最大尺寸就需要很小的数字.所以我改为检查X和Y的大小并设置一个大小条件的循环,这样如果X和Y不大,它就不会总是添加整个数组.
...
// %r13 holds X addr, %r14 holds Y addr.
addq $8, %r13 // I have tried incq …Run Code Online (Sandbox Code Playgroud) 我知道 8086 有一个 BIU 和一个 EU,这有助于处理器的流水线化。BIU 有一个 6 字节预取队列,用于提取指令指针指向的地址后面的字节。现在,当要执行的指令是跳转到另一个位置的指令时,预取的所有 6 个字节会发生什么情况?它们会被冲掉然后重新加载吗?(这会破坏处理器的流水线效率,不是吗?)
假设我使用编译器:gcc 4.8。还有来自英特尔的处理器,比如说 Skylake 或其他一些奇特的新系列。
检查这个问题:如何查看哪些标志 -march=native 将激活?; 如果我这样做gcc -march=native -E -v - </dev/null 2>&1 | grep cc1,这将为主机(即上述处理器skylake)喷出一些标志。
当 4.8 在 Skylake 处理器发布之前发布时,gcc 如何知道启用禁用的标志?其他较新的处理器系列呢?
因此,下一个问题是将编译器升级到最新的,以便为新的目标处理器准确和最佳地编译?
这个问题并不是真正针对 gcc/intel,我想知道其他人也如何保持处理器和编译器之间的同步。
compiler-construction optimization gcc intel compiler-optimization
在 x86 上的 64 位模式下,大多数 32 位算术运算会清除目标寄存器的前 32 位。如果算术运算是“cmov”指令,并且条件为假怎么办?(我看过的参考手册中似乎没有涵盖这种情况)。
据我了解,编写并随后执行 JIT 或自修改代码的一般、更抽象的过程如下所示。
从这篇关于 x86 上自修改代码的文章中我可以看出,手动缓存管理显然是没有必要的。我认为 aclflushopt是必要的,但 x86 1显然会在从具有新指令的位置加载时自动处理缓存失效,这样指令提取就永远不会过时。我的问题不是关于 x86,但我想将其包括在内以进行比较。
AArch64 中的情况稍微复杂一些,因为它区分了可共享域以及缓存操作的“可见性”程度。仅从 ARMv8/ARMv9 的官方文档中,我首先得出了这个猜测。
dsb ishst确保在继续之前已全部写入,isb sy确保从内存中提取后续指令。但DMB/DSB/ISB 的文档说“ISB 后面的指令是从缓存或内存中获取的”。这给我的印象是缓存控制操作确实是必要的。我的新猜测是这样的。
dsb ishst确保在继续之前已全部写入,ic ivau新代码占用的所有缓存行。但我又忍不住觉得这也不太对劲。过了一会儿,我在文档中发现了一些我错过的东西,并且在一篇论文中发现了几乎相同的东西。他们都给出了一个看起来像这样的例子。
dc cvau, Xn ; Clean cache to PoU, so the newly written code will be visible
dsb ish ; Wait for cleaning to finish
ic ivau, Xn ; Invalidate …Run Code Online (Sandbox Code Playgroud) 假设两个地址空间共享一块较大的非连续内存。系统可能希望在它们之间共享物理页表。这些表不会使用全局位(即使支持),并且如果支持的话会将它们绑定到asid。
这样做有直接的好处,因为数据缓存的污染比副本、更少的固定内存等污染要少。
页面遍历是否在任何已知架构中明确利用了这一点?如果是这样,这是否意味着mmu正在根据物理标签显式缓存和共享内部页面树节点?
很抱歉提出了多个问题;这确实是一件坏事。我正在尝试确定是否值得为此设计一个测量测试。
assembly ×3
cpu-cache ×2
intel ×2
x86-64 ×2
arm64 ×1
bigint ×1
gcc ×1
machine-code ×1
mmu ×1
optimization ×1
page-tables ×1
performance ×1
rdtsc ×1
tdm-gcc ×1
x86 ×1
x86-16 ×1