小编Pet*_*des的帖子

新的X86_64处理器寄存器的名称是什么?

在哪里可以找到用于此体系结构的新寄存器的名称?

我指的是X86中的寄存​​器,如EAX,ESP,EBX等.但我喜欢它们在64位.

我不认为它们与我拆解C代码时的情况相同,我得到r而不是e.

x86 assembly x86-64 cpu-registers

54
推荐指数
4
解决办法
7万
查看次数

装配 - CMP后的JG/JNLE/JL/JNGE

我不理解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,何时不会.

谢谢.

x86 assembly eflags

53
推荐指数
2
解决办法
12万
查看次数

为什么循环指令慢?英特尔无法有效实施吗?

LOOP(英特尔参考手动输入)递减ecx/rcx,然后如果非零则跳转.这很慢,但是英特尔不能廉价地把它变得很快吗? dec/jnz已经将宏观融合成 Sandybridge家族的一个 uop; 唯一的区别是设置标志.

loop关于各种微体系结构,来自Agner Fog的说明表:

  • K8/K10:7 m-ops
  • Bulldozer-family/Ryzen:1 m-op(与宏观融合测试和分支相同,或者jecxz)

  • P4:4次(相同jecxz)

  • P6(PII/PIII):8次
  • Pentium M,Core2:11 uops
  • Nehalem:6个uops.(11为loope/ loopne).吞吐量= 4c(loop)或7c(loope/ne).
  • SnB家族:7个uops.(11为loope/ loopne). 吞吐量=每5个循环一个,这是将循环计数器保留在内存中的瓶颈!jecxz只有2 uops,吞吐量与普通吞吐量相同jcc
  • Silvermont:7次
  • AMD Jaguar(低功耗):8 uops,5c吞吐量
  • 通过Nano3000:2 uops

难道解码器不能像lea rcx, [rcx-1]/ 那样解码jrcxz吗?这将是3 uops.至少那是没有地址大小前缀的情况,否则它必须使用ecx和截断RIP,EIP如果跳转; 也许奇怪的地址大小选择控制减量的宽度解释了许多uops?

或者更好,只需将其解码为不设置标志的融合分支和分支? dec ecx …

performance x86 assembly intel cpu-architecture

53
推荐指数
3
解决办法
6096
查看次数

要学习汇编 - 我应该从32位还是64位开始?

我真的很想学习装配.我非常擅长c/c ++,但希望更好地了解较低级别的内容.

我意识到之前已经提出了与装配相关的问题,但我只是在寻找一些特定于我的情况的方向:

我正在运行Windows 7,我对如何开始使用汇编感到困惑.我是否必须从x64开始,因为我正在运行Windows 7?有些人说"先从32位开始" - 我该如何做呢?我的操作系统与我为'32'或'64'位写入汇编的能力有什么关系.事实上,'n位'汇编意味着什么,其中n是一个数字?


编辑:

以下是一些帮助我开始组装的链接; 刚刚入门的其他人可能会发现它们很有帮助.随着我继续组装之旅,我将继续更新此列表:)

注意:正如我一直在学习的那样,我决定专注于使用masm32进行编程.因此,以下大多数资源都集中于此.

x86 assembly x86-64 low-level

52
推荐指数
2
解决办法
3万
查看次数

为什么允许gcc从结构中推测性地加载?

显示可能出错的gcc优化和用户代码的示例

下面的代码段中的函数'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)

c x86 assembly gcc compiler-optimization

52
推荐指数
5
解决办法
4140
查看次数

什么寄存器保存在ARM C调用约定中?

自从我上次编写手臂汇编程序以来已经有一段时间了,我对细节有点生疏.如果我从arm调用C函数,我只需要担心保存r0-r3和lr,对吧?

如果C函数使用任何其他寄存器,它是否负责保存堆栈中的那些并恢复它们?换句话说,编译器会生成代码来为C函数执行此操作.

例如,如果我在汇编程序函数中使用r10,我不必将其值放在堆栈或内存中,并在C调用后弹出/恢复它,是吗?

这是针对arm-eabi-gcc 4.3.0.

c assembly arm calling-convention function-call

51
推荐指数
5
解决办法
6万
查看次数

C 中 INT_MAX 和 __INT_MAX__ 之间的区别

2者有什么区别?__INT_MAX__据我所知,它是在没有添加库的情况下定义的,并且INT_MAX是在 中定义的limits.h,但是当我包含该库时,INT_MAX它会以__INT_MAX__任何一种方式扩展(或者 VSCode 是这么说的)。limits.h当它扩展到另一种时,为什么我还要使用它?

c limit

50
推荐指数
4
解决办法
6816
查看次数

如何在多核Intel CPU中共享高速缓存?

关于多核CPU或多处理器系统中使用的高速缓存存储器,我有几个问题.(虽然与编程没有直接关系,但是当一个人为多核处理器/多处理器系统编写软件时会产生很多反响,因此在这里问!)

  1. 在多处理器系统或多核处理器(Intel Quad Core,Core two Duo等......)中,每个cpu核心/处理器都有自己的缓存(数据和程序缓存)吗?

  2. 一个处理器/核心可以访问彼此的高速缓存,因为如果允许它们访问彼此的高速缓存,那么我认为可能存在较少的高速缓存未命中,如果特定处理器高速缓存没有一些数据但是其他一些处理器的缓存可能有它,从而避免从内存读入第一个处理器的缓存?这个假设是否有效且真实?

  3. 允许任何处理器访问其他处理器的高速缓冲存储器会有任何问题吗?

performance x86 intel multiprocessing cpu-cache

45
推荐指数
4
解决办法
2万
查看次数

当前的x86架构是否支持非临时负载(来自"正常"内存)?

我知道关于这个主题的多个问题,但是,我没有看到任何明确的答案或任何基准测量.因此,我创建了一个简单的程序,它使用两个整数数组.第一个数组a非常大(64 MB),第二个数组b很小,适合L1缓存.程序迭代a并将其元素添加到b模块化意义上的相应元素中(当到达结束时b,程序从其开始再次开始).测量的不同大小的L1缓存未命中数b如下:

在此输入图像描述

测量是在具有32 kiB L1数据高速缓存的Xeon E5 2680v3 Haswell型CPU上进行的.因此,在所有情况下,都b适合L1缓存.然而,大约16 kiB的b内存占用量大大增加了未命中数.这可能因为两者的负载预期ab导致缓存线失效从一开始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)

c c++ x86 caching prefetch

45
推荐指数
2
解决办法
1770
查看次数

尽快比较形式(a + sqrt(b))的两个值?

作为我编写的程序的一部分,我需要比较形式为a + sqrt(b)where abunsigned 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) = 90100a2+sqrt(b2) = 901000.00050050037512481206。最接近的浮点数就是90100。


由于sqrt()即使在现代的x86-64上作为sqrtsd指令完全内联时,该函数通常也非常昂贵,所以我试图避免sqrt()尽可能地调用。

通过平方运算删除sqrt还可以通过使所有计算都精确来避免舍入错误的任何危险。

如果相反,功能是这样的...

bool is_smaller(unsigned …
Run Code Online (Sandbox Code Playgroud)

c++ optimization algebra micro-optimization sqrt

45
推荐指数
1
解决办法
1737
查看次数