- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在英特尔酷睿双核上分析我们的一些核心数学,在研究各种求平方根的方法时,我注意到一些奇怪的事情:使用 SSE 标量运算,取倒数平方根的速度更快并将其相乘以获得 sqrt,而不是使用 native sqrt 操作码!
我正在使用类似的循环来测试它:
inline float TestSqrtFunction( float in );
void TestFunc()
{
#define ARRAYSIZE 4096
#define NUMITERS 16386
float flIn[ ARRAYSIZE ]; // filled with random numbers ( 0 .. 2^22 )
float flOut [ ARRAYSIZE ]; // filled with 0 to force fetch into L1 cache
cyclecounter.Start();
for ( int i = 0 ; i < NUMITERS ; ++i )
for ( int j = 0 ; j < ARRAYSIZE ; ++j )
{
flOut[j] = TestSqrtFunction( flIn[j] );
// unrolling this loop makes no difference -- I tested it.
}
cyclecounter.Stop();
printf( "%d loops over %d floats took %.3f milliseconds",
NUMITERS, ARRAYSIZE, cyclecounter.Milliseconds() );
}
我已经用 TestSqrtFunction 的几个不同的主体进行了尝试,并且我得到了一些确实令人摸不着头脑的计时。到目前为止,最糟糕的是使用 native sqrt() 函数并让“智能”编译器“优化”。在 24ns/float 时,使用 x87 FPU,这非常糟糕:
inline float TestSqrtFunction( float in )
{ return sqrt(in); }
我尝试的下一件事是使用内部函数强制编译器使用 SSE 的标量 sqrt 操作码:
inline void SSESqrt( float * restrict pOut, float * restrict pIn )
{
_mm_store_ss( pOut, _mm_sqrt_ss( _mm_load_ss( pIn ) ) );
// compiles to movss, sqrtss, movss
}
这更好,为 11.9ns/float。我也尝试过Carmack's wacky Newton-Raphson approximation technique ,它的运行速度甚至比硬件还要好,为 4.3ns/float,尽管误差为 210 中的 1(这对于我的目的来说太多了)。
最糟糕的是,我尝试使用 SSE 运算计算倒数平方根,然后使用乘法来获得平方根 ( x * 1/√x = √x )。尽管这需要两个相关操作,但它是迄今为止最快的解决方案,为 1.24ns/float,精确到 2-14:
inline void SSESqrt_Recip_Times_X( float * restrict pOut, float * restrict pIn )
{
__m128 in = _mm_load_ss( pIn );
_mm_store_ss( pOut, _mm_mul_ss( in, _mm_rsqrt_ss( in ) ) );
// compiles to movss, movaps, rsqrtss, mulss, movss
}
我的问题基本上是给出了什么? 为什么 SSE 的内置硬件平方根操作码比其他两个数学运算合成的要慢?
我确信这确实是操作本身的成本,因为我已经验证过:
(编辑:stephentyrone正确地指出,对长数字字符串的操作应该使用向量化SIMD打包操作,例如rsqrtps
- 但这里的数组数据结构是为了仅用于测试目的:我真正想要测量的是在无法矢量化的代码中使用的标量性能。)
最佳答案
sqrtss
给出正确舍入的结果。 rsqrtss
给出倒数的近似值,精确到大约 11 位。
sqrtss
正在生成更加准确的结果。 rsqrtss
存在于近似值足够但需要速度的情况。如果您阅读英特尔的文档,您还会发现一个指令序列(倒数平方根近似,后跟一个牛顿-拉夫森步骤),它提供了几乎完整的精度(如果我没记错的话,精度约为 23 位),并且仍然有点比 sqrtss
更快。
编辑:如果速度至关重要,并且您确实在循环中调用许多值,则应该使用这些指令的矢量化版本,rsqrtps
或 sqrtps
,两者每条指令都处理四个 float 。
关于performance - 为什么 SSE 标量 sqrt(x) 比 rsqrt(x) * x 慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1528727/
问题故障解决记录 -- Java RMI Connection refused to host: x.x.x.x .... 在学习JavaRMI时,我遇到了以下情况 问题原因:可
我正在玩 Rank-N-type 并尝试输入 x x .但我发现这两个函数可以以相同的方式输入,这很不直观。 f :: (forall a b. a -> b) -> c f x = x x g ::
这个问题已经有答案了: How do you compare two version Strings in Java? (31 个回答) 已关闭 8 年前。 有谁知道如何在Java中比较两个版本字符串
这个问题已经有答案了: How do the post increment (i++) and pre increment (++i) operators work in Java? (14 个回答)
下面是带有 -n 和 -r 选项的 netstat 命令的输出,其中目标字段显示压缩地址 (127.1/16)。我想知道 netstat 命令是否有任何方法或选项可以显示整个目标 IP (127.1.
我知道要证明 : (¬ ∀ x, p x) → (∃ x, ¬ p x) 证明是: theorem : (¬ ∀ x, p x) → (∃ x, ¬ p x) := begin intro n
x * x 如何通过将其存储在“auto 变量”中来更改?我认为它应该仍然是相同的,并且我的测试表明类型、大小和值显然都是相同的。 但即使 x * x == (xx = x * x) 也是错误的。什么
假设,我们这样表达: someIQueryable.Where(x => x.SomeBoolProperty) someIQueryable.Where(x => !x.SomeBoolProper
我有一个字符串 1234X5678 我使用这个正则表达式来匹配模式 .X|..X|X. 我得到了 34X 问题是为什么我没有得到 4X 或 X5? 为什么正则表达式选择执行第二种模式? 最佳答案 这里
我的一个 friend 在面试时遇到了这个问题 找到使该函数返回真值的 x 值 function f(x) { return (x++ !== x) && (x++ === x); } 面试官
这个问题在这里已经有了答案: 10年前关闭。 Possible Duplicate: Isn't it easier to work with foo when it is represented b
我是 android 的新手,我一直在练习开发一个针对 2.2 版本的应用程序,我需要帮助了解如何将我的应用程序扩展到其他版本,即 1.x、2.3.x、3 .x 和 4.x.x,以及一些针对屏幕分辨率
为什么案例 1 给我们 :error: TypeError: x is undefined on line... //case 1 var x; x.push(x); console.log(x);
代码优先: # CASE 01 def test1(x): x += x print x l = [100] test1(l) print l CASE01 输出: [100, 100
我正在努力温习我的大计算。如果我有将所有项目移至 'i' 2 个空格右侧的函数,我有一个如下所示的公式: (n -1) + (n - 2) + (n - 3) ... (n - n) 第一次迭代我必须
给定 IP 字符串(如 x.x.x.x/x),我如何或将如何计算 IP 的范围最常见的情况可能是 198.162.1.1/24但可以是任何东西,因为法律允许的任何东西。 我要带198.162.1.1/
在我作为初学者努力编写干净的 Javascript 代码时,我最近阅读了 this article当我偶然发现这一段时,关于 JavaScript 中的命名空间: The code at the ve
我正在编写一个脚本,我希望避免污染 DOM 的其余部分,它将是一个用于收集一些基本访问者分析数据的第 3 方脚本。 我通常使用以下内容创建一个伪“命名空间”: var x = x || {}; 我正在
我尝试运行我的test_container_services.py套件,但遇到了以下问题: docker.errors.APIError:500服务器错误:内部服务器错误(“ b'{” message
是否存在这两个 if 语句会产生不同结果的情况? if(x as X != null) { // Do something } if(x is X) { // Do something } 编
我是一名优秀的程序员,十分优秀!