在哪里可以找到用于此体系结构的新寄存器的名称?
我指的是X86中的寄存器,如EAX,ESP,EBX等.但我喜欢它们在64位.
我不认为它们与我拆解C代码时的情况相同,我得到r而不是e.
我不理解JG/JNLE/JL/JNGECMP之后的说明.
例如,如果我有:
CMP al,dl
jg label1
Run Code Online (Sandbox Code Playgroud)
当al=101; dl =200.
我们问jg什么?是al>dl吗?还是al-dl>0?
在下一个代码上相同的prolbem:
test al,dl
jg label1
Run Code Online (Sandbox Code Playgroud)
我不明白我们比较什么,以及我们问什么" jg".
换句话说,我不明白我们何时会跳转到label1,何时不会.
谢谢.
LOOP(英特尔参考手动输入)递减ecx/rcx,然后如果非零则跳转.这很慢,但是英特尔不能廉价地把它变得很快吗? dec/jnz已经将宏观融合成 Sandybridge家族的一个 uop; 唯一的区别是设置标志.
loop关于各种微体系结构,来自Agner Fog的说明表:
Bulldozer-family/Ryzen:1 m-op(与宏观融合测试和分支相同,或者jecxz)
P4:4次(相同jecxz)
loope/ loopne).吞吐量= 4c(loop)或7c(loope/ne).loope/ loopne). 吞吐量=每5个循环一个,这是将循环计数器保留在内存中的瓶颈!jecxz只有2 uops,吞吐量与普通吞吐量相同jcc难道解码器不能像lea rcx, [rcx-1]/ 那样解码jrcxz吗?这将是3 uops.至少那是没有地址大小前缀的情况,否则它必须使用ecx和截断RIP,EIP如果跳转; 也许奇怪的地址大小选择控制减量的宽度解释了许多uops?
或者更好,只需将其解码为不设置标志的融合分支和分支? dec ecx …
我真的很想学习装配.我非常擅长c/c ++,但希望更好地了解较低级别的内容.
我意识到之前已经提出了与装配相关的问题,但我只是在寻找一些特定于我的情况的方向:
我正在运行Windows 7,我对如何开始使用汇编感到困惑.我是否必须从x64开始,因为我正在运行Windows 7?有些人说"先从32位开始" - 我该如何做呢?我的操作系统与我为'32'或'64'位写入汇编的能力有什么关系.事实上,'n位'汇编意味着什么,其中n是一个数字?
编辑:
以下是一些帮助我开始组装的链接; 刚刚入门的其他人可能会发现它们很有帮助.随着我继续组装之旅,我将继续更新此列表:)
注意:正如我一直在学习的那样,我决定专注于使用masm32进行编程.因此,以下大多数资源都集中于此.
Agner Fog的软件优化资源,包括在不同平台(Windows与Linux/OS X)上调用约定的一些好东西,以及如何有效地执行特定事务的大量示例.不适合初学者,但对于中级到高级读者来说非常棒.
(他还为英特尔和AMD CPU的每条指令提供了详细的性能信息,非常适合严格的性能微优化.一些初学者可能想要了解其中的一些内容,开始考虑CPU的工作原理,以及为什么你可以做一些事情方式而不是另一种方式.)
下面的代码段中的函数'foo'将只加载一个结构成员A或B; 至少这是未经优化的代码的意图.
typedef struct {
int A;
int B;
} Pair;
int foo(const Pair *P, int c) {
int x;
if (c)
x = P->A;
else
x = P->B;
return c/102 + x;
}
Run Code Online (Sandbox Code Playgroud)
这是gcc -O3给出的:
mov eax, esi
mov edx, -1600085855
test esi, esi
mov ecx, DWORD PTR [rdi+4] <-- ***load P->B**
cmovne ecx, DWORD PTR [rdi] <-- ***load P->A***
imul edx
lea eax, [rdx+rsi]
sar esi, 31
sar eax, 6
sub eax, esi
add eax, ecx
ret …Run Code Online (Sandbox Code Playgroud) 自从我上次编写手臂汇编程序以来已经有一段时间了,我对细节有点生疏.如果我从arm调用C函数,我只需要担心保存r0-r3和lr,对吧?
如果C函数使用任何其他寄存器,它是否负责保存堆栈中的那些并恢复它们?换句话说,编译器会生成代码来为C函数执行此操作.
例如,如果我在汇编程序函数中使用r10,我不必将其值放在堆栈或内存中,并在C调用后弹出/恢复它,是吗?
这是针对arm-eabi-gcc 4.3.0.
2者有什么区别?__INT_MAX__据我所知,它是在没有添加库的情况下定义的,并且INT_MAX是在 中定义的limits.h,但是当我包含该库时,INT_MAX它会以__INT_MAX__任何一种方式扩展(或者 VSCode 是这么说的)。limits.h当它扩展到另一种时,为什么我还要使用它?
关于多核CPU或多处理器系统中使用的高速缓存存储器,我有几个问题.(虽然与编程没有直接关系,但是当一个人为多核处理器/多处理器系统编写软件时会产生很多反响,因此在这里问!)
在多处理器系统或多核处理器(Intel Quad Core,Core two Duo等......)中,每个cpu核心/处理器都有自己的缓存(数据和程序缓存)吗?
一个处理器/核心可以访问彼此的高速缓存,因为如果允许它们访问彼此的高速缓存,那么我认为可能存在较少的高速缓存未命中,如果特定处理器高速缓存没有一些数据但是其他一些处理器的缓存可能有它,从而避免从内存读入第一个处理器的缓存?这个假设是否有效且真实?
允许任何处理器访问其他处理器的高速缓冲存储器会有任何问题吗?
我知道关于这个主题的多个问题,但是,我没有看到任何明确的答案或任何基准测量.因此,我创建了一个简单的程序,它使用两个整数数组.第一个数组a非常大(64 MB),第二个数组b很小,适合L1缓存.程序迭代a并将其元素添加到b模块化意义上的相应元素中(当到达结束时b,程序从其开始再次开始).测量的不同大小的L1缓存未命中数b如下:
测量是在具有32 kiB L1数据高速缓存的Xeon E5 2680v3 Haswell型CPU上进行的.因此,在所有情况下,都b适合L1缓存.然而,大约16 kiB的b内存占用量大大增加了未命中数.这可能因为两者的负载预期a并b导致缓存线失效从一开始b在这一点上.
绝对没有理由保留a缓存中的元素,它们只使用一次.因此,我运行一个具有非时间负载a数据的程序变体,但未命中数没有改变.我还运行了一个非暂时预取a数据的变体,但仍然有相同的结果.
我的基准代码如下(没有显示非时间预取的变体):
int main(int argc, char* argv[])
{
uint64_t* a;
const uint64_t a_bytes = 64 * 1024 * 1024;
const uint64_t a_count = a_bytes / sizeof(uint64_t);
posix_memalign((void**)(&a), 64, a_bytes);
uint64_t* b;
const uint64_t b_bytes = atol(argv[1]) * 1024;
const uint64_t b_count = b_bytes …Run Code Online (Sandbox Code Playgroud) 作为我编写的程序的一部分,我需要比较形式为a + sqrt(b)where a和bunsigned integer的两个值。由于这是紧密循环的一部分,因此我希望此比较尽可能快地运行。(如果重要的话,我正在x86-64机器上运行代码,并且无符号整数不大于10 ^ 6。此外,我知道这样的事实a1<a2。)
作为独立功能,这就是我要优化的功能。我的数字是足够小的整数,可以double(或什至float)精确地表示它们,但是sqrt结果中的舍入误差不能改变结果。
// known pre-condition: a1 < a2 in case that helps
bool is_smaller(unsigned a1, unsigned b1, unsigned a2, unsigned b2) {
return a1+sqrt(b1) < a2+sqrt(b2); // computed mathematically exactly
}
Run Code Online (Sandbox Code Playgroud)
测试用例:is_smaller(900000, 1000000, 900001, 998002)应返回true,但如@wim注释所示,sqrtf()将其返回false。因此将(int)sqrt()截断为整数。
a1+sqrt(b1) = 90100和a2+sqrt(b2) = 901000.00050050037512481206。最接近的浮点数就是90100。
由于sqrt()即使在现代的x86-64上作为sqrtsd指令完全内联时,该函数通常也非常昂贵,所以我试图避免sqrt()尽可能地调用。
通过平方运算删除sqrt还可以通过使所有计算都精确来避免舍入错误的任何危险。
如果相反,功能是这样的...
bool is_smaller(unsigned …Run Code Online (Sandbox Code Playgroud)