在x86-64中实现rint() [英] Implementing rint() in x86-64
本文介绍了在x86-64中实现rint()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
pre $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $
fld x
frndint
}
}
在x64中不起作用。有_mm_round_sd()但需要SSE4。什么是有效的无分支方式获得相同的行为?
解决方案
#include< emmintrin.h>
static inline double rint(double const x){
return(double)_mm_cvtsd_si32(_mm_load_sd(& x));
查看Agner Fog's 为C ++优化C ++手册
32位模式
//例14.19
static inline int lrint(double const x){//舍入到最近的整数
int n;
#if defined(__ unix__)||定义(__ GNUC__)
// 32位Linux,Gnu / AT& T语法:
__asm(fldl%1 \\\
fistpl%0:= m(n):m (x):记忆);
#else
// 32位Windows,Intel / MASM语法:
__asm fld qword ptr x;
__asm fistp dword ptr n;
#endif
return n;
$ / code $ / pre
$ b $ 64位模式
//例14.21。 //仅适用于SSE2或x64
#include< emmintrin.h>
static inline int lrint(double const x){
return _mm_cvtsd_si32(_mm_load_sd(& x));
code
我刚刚意识到该方法将限制值为+/- 2 ^ 31。如果你想要SSE2版本更大的版本,这很复杂(但SSE4.1很容易)。例如,在文件vectorf128.h中查看Agner Fog的Vector类中的round函数。
MSVC 2012 doesn't have the rint() function. For 32-bit, I'm using the following:
double rint(double x) {
__asm {
fld x
frndint
}
}
This doesn't work in x64. There's _mm_round_sd() but that requires SSE4. What is an efficient preferrably branchless way of getting the same behavior?
解决方案 rint 64-bit mode
#include <emmintrin.h>
static inline double rint (double const x) {
return (double)_mm_cvtsd_si32(_mm_load_sd(&x));
}
See Agner Fog's Optimizing C++ manual for lrint
32-bit mode
// Example 14.19
static inline int lrint (double const x) { // Round to nearest integer
int n;
#if defined(__unix__) || defined(__GNUC__)
// 32-bit Linux, Gnu/AT&T syntax:
__asm ("fldl %1 \n fistpl %0 " : "=m"(n) : "m"(x) : "memory" );
#else
// 32-bit Windows, Intel/MASM syntax:
__asm fld qword ptr x;
__asm fistp dword ptr n;
#endif
return n;
}
64-bit mode
// Example 14.21. // Only for SSE2 or x64
#include <emmintrin.h>
static inline int lrint (double const x) {
return _mm_cvtsd_si32(_mm_load_sd(&x));
}
Edit:
I just realized that this method will limit the values to to +/- 2^31. If you want a version with a larger range with SSE2 it's complicated (but easy with SSE4.1). See the round function in Agner Fog's Vector Class in the file vectorf128.h for an example.
这篇关于在x86-64中实现rint()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文