标签: x86-64

为什么 __int128_t 在 x86-64 GCC 上比 long long 快?

这是我的测试代码:

#include <chrono>
#include <iostream>
#include <cstdlib>
using namespace std;

using ll = long long;

int main()
{
    __int128_t a, b;
    ll x, y;

    a = rand() + 10000000;
    b = rand() % 50000;
    auto t0 = chrono::steady_clock::now();
    for (int i = 0; i < 100000000; i++)
    {
        a += b;
        a /= b;
        b *= a;
        b -= a;
        a %= b;
    }
    cout << chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - t0).count() << ' '
         << (ll)a % 100000 << '\n';

    x = …
Run Code Online (Sandbox Code Playgroud)

c++ performance x86-64 cpu-architecture integer-division

43
推荐指数
2
解决办法
3808
查看次数

在x86/x86_64处理器上使用LFENCE指令是否有意义?

通常在互联网上我发现LFENCE在处理器x86中没有任何意义,即它什么都不做,所以相反MFENCE我们可以绝对无痛地使用SFENCE,因为MFENCE= SFENCE+ LFENCE= SFENCE+ NOP= SFENCE.

但是如果LFENCE没有意义,那么为什么我们有四种方法在x86/x86_64中建立顺序一致性:

  1. LOAD(没有围栏)和STORE+MFENCE
  2. LOAD (没有围栏)和 LOCK XCHG
  3. MFENCE+ LOADSTORE(没有围栏)
  4. LOCK XADD(0)和STORE(没有围栏)

取自这里:http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html

以及Herb Sutter在第34页底部的表演:https://skydrive.live.com/view.aspx?status = 4E86B0CF20EF15AD!24884&app = WordPdf&wdo = 2&authkey =!AMtj_EflYn2507c

如果LFENCE没有做任何事情,那么方法(3)将具有以下含义:SFENCE + LOAD and STORE (without fence)但是SFENCE之前没有任何意义LOAD.即如果LFENCE什么都不做,方法(3)没有意义.

LFENCE在处理器x86/x86_64中是否有任何意义上的指令?

回答:

1. …

x86 assembly x86-64 atomic memory-barriers

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

比较 Fortran 和 C++ 汇编程序的 int = floor(sqrt(...))

我在 Fortran 和 C++ 中分别实现了一个函数:

#include <math.h>

void dbl_sqrt_c(double *x, double *y){
   *y = sqrt(*x - 1.0);
   return;
}
Run Code Online (Sandbox Code Playgroud)
pure subroutine my_dbl_sqrt(x,y) bind(c, name="dbl_sqrt_fort")
   USE, INTRINSIC :: ISO_C_BINDING
   implicit none
   real(kind=c_double), intent(in)  :: x
   real(kind=c_double), intent(out) :: y

   y = sqrt(x - 1d0)
end subroutine my_dbl_sqrt
Run Code Online (Sandbox Code Playgroud)

我在编译器资源管理器中比较了它们:

Fortran:https : //godbolt.org/z/froz4rx97
C++:https : //godbolt.org/z/45aex99Yz

我阅读汇编程序的方式,它们基本上做相同的事情,但是 C++ 检查 sqrt 的参数是否为负,而 Fortran 则没有。我使用 googles 基准比较了它们的性能,但它们非常匹配:

--------------------------------------------------------
Benchmark              Time             CPU   Iterations
--------------------------------------------------------
bm_dbl_c/8          2.07 ns         2.07 ns    335965892
bm_dbl_fort/8       2.06 ns         2.06 …
Run Code Online (Sandbox Code Playgroud)

c++ performance assembly x86-64

40
推荐指数
2
解决办法
2462
查看次数

原子变量是否无锁?

当我们谈论原子变量时,例如C++ 11 atomic<>,它是否可以免费锁定?或者锁定是不同的东西?如果我使用原子变量管理队列,它会比无锁队列慢吗?

c++ multithreading x86-64 atomic c++11

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

gcc中有128位整数吗?

我想要一个128位整数,因为我想存储两个64位数的乘法结果.在gcc 4.4及以上版本中有没有这样的东西?

c gcc x86-64 bigint 128-bit

39
推荐指数
3
解决办法
6万
查看次数

在msbuild中使用32位"Program Files"目录

在64位版本的Windows中,32位软件安装在"c:\ program files(x86)"中.这意味着你不能使用$(programfiles)来获取(32位)软件的路径.所以我需要一个$(ProgramFiles32)来克服我的MSBuild项目.我不想根据运行的操作系统更改项目.

我有一个解决方案,我会发布,但也许有一个更容易/更好的方式.

msbuild 64-bit x86 x86-64 program-files

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

通过linux x86-64函数调用保留了哪些寄存器

我相信我理解linux x86-64 ABI如何使用寄存器和堆栈将参数传递给函数(参见之前的ABI讨论).我感到困惑的是,在函数调用中是否预期保留了哪些寄存器.也就是说,哪些寄存器被保证不被破坏?

linux assembly x86-64 abi

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

x86_64 将 64 位寄存器减少到 32 位并保留零或非零状态的最佳方法

我正在寻找最快/最节省空间的方法,将 64 位寄存器减少为 32 位寄存器,仅保留 64 位寄存器的零/非零状态。

我目前适用于所有值的最佳想法是popcntq
(1c tput,主流英特尔上的 3c 延迟,5 字节代码大小):

// rax is either zero or non-zero
popcntq %rax, %rax
// eax will be zero if rax was zero, otherwise it will be non-zero
Run Code Online (Sandbox Code Playgroud)

注意:直接使用 32 位是行不通的eax:如果rax说 的2^61零/非零状态eax与 的不同rax

有没有更好的巧妙方法?

assembly x86-64 micro-optimization

38
推荐指数
2
解决办法
3239
查看次数

如果在64位代码中使用32位int 0x80 Linux ABI会发生什么?

int 0x80在Linux上总是调用32位ABI,不管是什么模式,这就是所谓的:在args ebx,ecx...和系统调用号的/usr/include/asm/unistd_32.h.(或者在没有编译的64位内核上崩溃CONFIG_IA32_EMULATION).

64位代码应该使用syscall,从呼叫号码/usr/include/asm/unistd_64.h,并在args rdi,rsi等见什么调用约定UNIX和Linux系统上的i386和x86-64调用.如果您的问题被打上这样一个重复的,看你怎么说链接,细节应当使32位或64位代码的系统调用. 如果你想了解到底发生了什么,请继续阅读.


sys_write系统调用比syscall系统调用快,所以使用本机64位,int 0x80除非你正在编写多格式机器代码,当执行32或64位时运行相同的机器代码.(syscall始终以32位模式返回,因此它在64位用户空间中没有用,尽管它是有效的x86-64指令.)

相关:Linux系统的权威指南(在x86上)调用如何进行sysenterint 0x8032位系统调用,或sysenter64位系统调用,或调用vDSO进行"虚拟"系统调用syscall.加上有关系统调用的背景知识.


使用gettimeofday可以编写将以32位或64位模式组合的内容,因此它可以int 0x80在微基准测试结束时使用.

标准化函数和系统调用约定的官方i386和x86-64 System V psABI文档的当前PDF文件链接自https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI.

有关初学者指南,x86手册,官方文档和性能优化指南/资源,请参阅标记wiki.


但是,由于人们不断发布与使用代码的问题exit_group()在64位代码,或不小心建立64位二进制文件从源代码对于32位写的,我不知道是什么确切不会对当前的Linux怎样呢?

是否int 0x80保存/恢复所有的64位寄存器?它会将任何寄存器截断为32位吗?如果传递上半部分非零的指针args会发生什么?

如果你传递32位指针它是否有效?

linux assembly x86-64 system-calls abi

36
推荐指数
1
解决办法
4783
查看次数

如何在Linux AMD64中使用fs/gs寄存器?

在x86-64架构中,两个寄存器具有特殊用途:FS和GS.在linux 2.6.*中,FS寄存器似乎用于存储线程本地信息.

  • 那是对的吗?
  • 什么存储在fs:0?是否有描述此内容的C结构?
  • 那么GS的用途是什么?

architecture linux x86 assembly x86-64

35
推荐指数
3
解决办法
1万
查看次数