标签: x86-64

为什么uint_least16_t比uint_fast16_t快于x86_64中的乘法?

关于uint_fast*_t类型族,C标准还不太清楚.在gcc-4.4.4 linux x86_64系统上,类型uint_fast16_tuint_fast32_t大小均为8个字节.但是,8字节数的乘法似乎比4字节数的乘法慢得多.以下代码演示了:

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

int
main ()
{
  uint_least16_t p, x;
  int count;

  p = 1;
  for (count = 100000; count != 0; --count)
    for (x = 1; x != 50000; ++x)
      p*= x;

  printf("%"PRIuLEAST16, p);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我得到了在程序上运行time命令

real 0m7.606s
user 0m7.557s
sys  0m0.019s
Run Code Online (Sandbox Code Playgroud)

如果我将类型更改为uint_fast16_t(和printf修饰符),则时间变为

real 0m12.609s
user 0m12.593s
sys  0m0.009s
Run Code Online (Sandbox Code Playgroud)

那么,如果stdint.h头文件uint_fast16_t(以及uint_fast32_t)定义为4字节类型,那会不会更好?

c unsigned x86-64 multiplication

11
推荐指数
2
解决办法
2983
查看次数

REX.B覆盖是否适用于MOVSS指令?

我正在为64位x86生成以下指令:

41 F3 0F 10 46 10       movss   XMM0,014h[R14]
Run Code Online (Sandbox Code Playgroud)

不幸的是,它在该行上出现故障.gdb将其反汇编为:

0x0000000000402054 <+320>:   rex.B
0x0000000000402055 <+321>:   movss  0x14(%rsi),%xmm0
Run Code Online (Sandbox Code Playgroud)

请注意,无法识别rex.B覆盖,索引是RSI而不是R14.

指令无效吗?在AMD 64位指令参考中,我找不到任何迹象表明此编码无效.

objdump也无法将其识别为有效指令:

41                      rex.B
f3 0f 10 46 10          movss  0x10(%rsi),%xmm0
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?

assembly x86-64

11
推荐指数
1
解决办法
629
查看次数

如何在x86_64汇编中读取STDIN的输入?

我正在尝试学习x86_64程序集,我今天正在尝试标准输入输出并偶然发现这个帖子学习程序集 - echo程序名称如何从STDIN读取输入(使用SYSCALL指令)?特别是如果我知道输入将始终是一个整数,我想将其读入寄存器?

编辑: @Daniel Kozar在下面的回答帮助我理解了STDIN和STDOUT如何与Linux上的SYSCALL指令一起工作.我试图编写一个小程序,它从控制台输入中读取一个数字并打印与该数字对应的ascii字符.假如你输入65作为输入,你应该得到A作为输出.还有一个新的线条角色.如果有的话,它可以帮助任何其他人:-)

section .text
    global _start

_start:
    mov rdi, 0x0      ; file descriptor = stdin = 0
    lea rsi, [rsp+8]  ; buffer = address to store the bytes read
    mov rdx, 0x2      ; number of bytes to read
    mov rax, 0x0      ; SYSCALL number for reading from STDIN
    syscall           ; make the syscall

    xor rax, rax      ; clear off rax
    mov rbx, [rsp+8]  ; read the first byte read into rsp+8 by STDIN call …
Run Code Online (Sandbox Code Playgroud)

assembly stdin x86-64

11
推荐指数
1
解决办法
2万
查看次数

syscall是x86_64上的指令吗?

我想检查在glibc中执行系统调用的代码.我发现了这样的事情.

ENTRY (syscall)
    movq %rdi, %rax     /* Syscall number -> rax.  */
    movq %rsi, %rdi     /* shift arg1 - arg5.  */
    movq %rdx, %rsi
    movq %rcx, %rdx
    movq %r8, %r10
    movq %r9, %r8
    movq 8(%rsp),%r9    /* arg6 is on the stack.  */
    syscall         /* Do the system call.  */
    cmpq $-4095, %rax   /* Check %rax for error.  */
    jae SYSCALL_ERROR_LABEL /* Jump to error handler if error.  */
L(pseudo_end):
    ret         /* Return to caller.  */
Run Code Online (Sandbox Code Playgroud)

现在我的问题是系统调用(在cmpq指令之前)是否是指令?其次,如果它是一个指令,ENTRY(系统调用)的含义是什么?ENTRY的同名(我不知道ENTRY是什么)和指令?其次,L(pseudo_end)是什么?

c linux gcc x86-64 machine-instruction

11
推荐指数
2
解决办法
8114
查看次数

指令级分析:指令指针的含义?

在汇编指令级别分析代码时,如果现代CPU不按顺序或按顺序执行指令,那么指令指针的位置真正意味着什么呢?例如,假设以下x64汇编代码:

mov RAX, [RBX];         // Assume a cache miss here.
mov RSI, [RBX + RCX];   // Another cache miss.             
xor R8, R8;        
add RDX, RAX;           // Dependent on the load into RAX.
add RDI, RSI;           // Dependent on the load into RSI.
Run Code Online (Sandbox Code Playgroud)

指令指针大部分时间用在哪条指令上?我可以为所有人想出好的论点:

  • mov RAX, [RBX] 大概需要100个周期,因为这是一个缓存未命中.
  • mov RSI, [RBX + RCX]也需要100个周期,但可能与前一个指令并行执行.它甚至意味着指令指针位于其中一个或另一个上?
  • xor R8, R8 可能在内存加载完成之前执行乱序并完成,但指令指针可能会保留在此处,直到所有先前的指令也完成为止.
  • add RDX, RAX生成管道停顿,因为它RAX是在缓慢的缓存未命中加载之后实际使用值的指令.
  • add RDI, RSI也停滞,因为它依赖于负载RSI.

performance assembly profiling x86-64 low-level

11
推荐指数
1
解决办法
891
查看次数

在64位Linux中,内核占用了哪个地址空间?

64位Linux内核的地址空间是多少,也就是说,它所使用的代码,堆栈,堆和数据段的地址范围是多少.

linux x86-64 linux-kernel

11
推荐指数
1
解决办法
8718
查看次数

矢量化模运算

我正在尝试编写一些合理快速的组件向量加法代码.我正在使用(签名,我相信)64位整数.

功能是

void addRq (int64_t* a, const int64_t* b, const int32_t dim, const int64_t q) {
    for(int i = 0; i < dim; i++) {
        a[i] = (a[i]+b[i])%q; // LINE1
    }
}
Run Code Online (Sandbox Code Playgroud)

我在icc -std=gnu99 -O3IvyBridge(SSE4.2和AVX,但不是AVX2)上编译(icc以便我以后可以使用SVML).

我的基线是%q从LINE1中删除.100(迭代)函数调用dim=11221184需要1.6秒.ICC自动矢量化SSE代码; 大.

我真的想做模块化的补充.使用%q,ICC不会自动向量化代码,它在11.8秒(!)内运行.即使忽略了之前尝试的自动矢量化,这似乎仍然过分.

由于我没有AVX2,SSE的矢量化需要SVML,这也许就是为什么ICC没有自动矢量化的原因.无论如何,这是我尝试对内循环进行矢量化:

__m128i qs = _mm_set1_epi64x(q);
for(int i = 0; i < dim; i+=2) {
    __m128i xs = _mm_load_si128((const __m128i*)(a+i));
    __m128i ys = _mm_load_si128((const __m128i*)(b+i));
    __m128i zs = _mm_add_epi64(xs,ys);
    zs = _mm_rem_epi64(zs,qs);
    _mm_store_si128((__m128i*)(a+i),zs);
}
Run Code Online (Sandbox Code Playgroud)

主循环的汇编是: …

c assembly sse x86-64 intrinsics

11
推荐指数
1
解决办法
1401
查看次数

分支预测会导致非法指令吗?

在以下伪代码中:

if (rdtscp supported by hardware) {
    Invoke "rdtscp" instruction
} else {
    Invoke "rdtsc" instruction
}
Run Code Online (Sandbox Code Playgroud)

假设CPU不支持该rdtscp指令,因此我们回退到else语句.

如果CPU错误预测分支,指令管道是否可能尝试执行rdtscp并抛出Illgal Instruction错误?

assembly x86-64 cpu-architecture branch-prediction

11
推荐指数
1
解决办法
542
查看次数

为什么x86-64的jmpq只需要32位长度的地址?

当我objdump -D用来反汇编二进制时,典型的代码jmpq就像e9 7f fe ff ff是,用于表示负偏移.但是,x86-64的地址是64(48)位(据我所知),那么这个32位地址如何7f fe ff ff表示64位绝对地址的负偏移?

此外,还有像任何其他指令jmpjmpq,但有64位地址位移?我怎样才能找到英特尔或AMD手册中的说明(我搜索jmpq但没有找到任何内容)?


当我搜索时,它似乎被称为RIP相对寻址.似乎并非所有说明都这样做.是否有64位相对寻址?如果是间接跳转,64位绝对地址将在寄存器或内存中,对吧?

assembly x86-64 computer-architecture

11
推荐指数
2
解决办法
3954
查看次数

Perf启动开销:为什么执行MOV + SYS_exit的简单静态可执行文件有如此多的停顿周期(和指令)?

我试图了解如何衡量性能并决定编写非常简单的程序:

section .text
    global _start

_start:
    mov rax, 60
    syscall
Run Code Online (Sandbox Code Playgroud)

我用perf stat ./bin 这个程序运行我感到惊讶的stalled-cycles-frontend是太高了.

      0.038132      task-clock (msec)         #    0.148 CPUs utilized          
             0      context-switches          #    0.000 K/sec                  
             0      cpu-migrations            #    0.000 K/sec                  
             2      page-faults               #    0.052 M/sec                  
       107,386      cycles                    #    2.816 GHz                    
        81,229      stalled-cycles-frontend   #   75.64% frontend cycles idle   
        47,654      instructions              #    0.44  insn per cycle         
                                              #    1.70  stalled cycles per insn
         8,601      branches                  #  225.559 M/sec                  
           929      branch-misses             #   10.80% of all branches        

   0.000256994 seconds time elapsed …
Run Code Online (Sandbox Code Playgroud)

linux performance assembly x86-64 perf

11
推荐指数
1
解决办法
155
查看次数