这是我的测试代码:
#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) 通常在互联网上我发现LFENCE在处理器x86中没有任何意义,即它什么都不做,所以相反MFENCE我们可以绝对无痛地使用SFENCE,因为MFENCE= SFENCE+ LFENCE= SFENCE+ NOP= SFENCE.
但是如果LFENCE没有意义,那么为什么我们有四种方法在x86/x86_64中建立顺序一致性:
LOAD(没有围栏)和STORE+MFENCELOAD (没有围栏)和 LOCK XCHGMFENCE+ LOAD和STORE(没有围栏)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. …
我在 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++ 11 atomic<>,它是否可以免费锁定?或者锁定是不同的东西?如果我使用原子变量管理队列,它会比无锁队列慢吗?
我想要一个128位整数,因为我想存储两个64位数的乘法结果.在gcc 4.4及以上版本中有没有这样的东西?
在64位版本的Windows中,32位软件安装在"c:\ program files(x86)"中.这意味着你不能使用$(programfiles)来获取(32位)软件的路径.所以我需要一个$(ProgramFiles32)来克服我的MSBuild项目.我不想根据运行的操作系统更改项目.
我有一个解决方案,我会发布,但也许有一个更容易/更好的方式.
我相信我理解linux x86-64 ABI如何使用寄存器和堆栈将参数传递给函数(参见之前的ABI讨论).我感到困惑的是,在函数调用中是否预期保留了哪些寄存器.也就是说,哪些寄存器被保证不被破坏?
我正在寻找最快/最节省空间的方法,将 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
有没有更好的巧妙方法?
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上)调用如何进行sysenter或int 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手册,官方文档和性能优化指南/资源,请参阅x86标记wiki.
但是,由于人们不断发布与使用代码的问题exit_group()在64位代码,或不小心建立64位二进制文件从源代码对于32位写的,我不知道是什么确切不会对当前的Linux怎样呢?
是否int 0x80保存/恢复所有的64位寄存器?它会将任何寄存器截断为32位吗?如果传递上半部分非零的指针args会发生什么?
如果你传递32位指针它是否有效?
在x86-64架构中,两个寄存器具有特殊用途:FS和GS.在linux 2.6.*中,FS寄存器似乎用于存储线程本地信息.