相关疑难解决方法(0)

浮点除法与浮点乘法

通过编码是否有任何(非微优化)性能增益

float f1 = 200f / 2
Run Code Online (Sandbox Code Playgroud)

在比较中

float f2 = 200f * 0.5
Run Code Online (Sandbox Code Playgroud)

几年前我的一位教授告诉我,浮点除法比浮点乘法慢,但没有详细说明原因.

这句话适用于现代PC架构吗?

UPDATE1

关于评论,请同时考虑这个案例:

float f1;
float f2 = 2
float f3 = 3;
for( i =0 ; i < 1e8; i++)
{
  f1 = (i * f2 + i / f3) * 0.5; //or divide by 2.0f, respectively
}
Run Code Online (Sandbox Code Playgroud)

更新2 从评论中引用:

[我想]知道什么是算法/架构要求导致>除法在硬件上比复制要复杂得多

c++ floating-point micro-optimization

67
推荐指数
5
解决办法
5万
查看次数

Newton Raphson与SSE2 - 有人可以解释我这3行

我正在阅读这份文件:http://software.intel.com/en-us/articles/interactive-ray-tracing

我偶然发现了这三行代码:

SIMD版本已经快了很多,但我们可以做得更好.英特尔为SSE2指令集添加了快速1/sqrt(x)函数.唯一的缺点是它的精度有限.我们需要精度,所以我们使用Newton-Rhapson来改进它:

 __m128 nr = _mm_rsqrt_ps( x ); 
 __m128 muls = _mm_mul_ps( _mm_mul_ps( x, nr ), nr ); 
 result = _mm_mul_ps( _mm_mul_ps( half, nr ), _mm_sub_ps( three, muls ) ); 
Run Code Online (Sandbox Code Playgroud)

此代码假定存在名为"half"(四次0.5f)和变量"three"(四次3.0f)的__m128变量.

我知道如何使用牛顿拉夫森计算函数的零点,我知道如何使用它来计算一个数的平方根,但我看不出这些代码如何执行它.

有人可以向我解释一下吗?

c c++ math sse newtons-method

28
推荐指数
1
解决办法
2648
查看次数

是否可以滚动明显更快的sqrt版本

在我正在分析的应用程序中,我发现在某些情况下,此功能可以占用总执行时间的10%.

我已经看到多年来使用偷偷摸摸的浮点技巧进行了更快的sqrt实现的讨论,但我不知道现代CPU上是否有这样的东西已经过时了.

正在使用MSVC++ 2008编译器,以供参考......虽然我认为sqrt不会增加太多开销.

有关modf函数的类似讨论,另请参见此处.

编辑:作为参考,是一种广泛使用的方法,但它实际上更快?这些天SQRT有多少个周期?

c++ optimization sqrt

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

为什么GCC或Clang在使用快速数学时不能优化1指令的倒数

有谁知道为什么GCC/Clang不会在下面的代码示例中优化函数test1,只是在使用fast-math选项时只使用RCPPS指令?是否有另一个编译器标志会生成此代码?

typedef float float4 __attribute__((vector_size(16)));

float4 test1(float4 v)
{
    return 1.0f / v;
}
Run Code Online (Sandbox Code Playgroud)

您可以在此处查看已编译的输出:https://goo.gl/jXsqat

c++ sse simd compiler-optimization fast-math

15
推荐指数
2
解决办法
1209
查看次数

如何在Windows异常处理程序中设置MMX寄存器以模拟不受支持的3DNow!说明

我正在尝试重振使用3DNow的旧Win32游戏!指令集进行3D渲染.

在像Win7这样的现代操作系统上 - 不允许像FPADD或FPMUL这样的Win10指令,程序会抛出异常.

自从3DNow的数量!游戏使用的指令非常有限,在我的VS2008 MFC程序中,我试图使用向量异常处理来获取MMX寄存器的值,模拟3DNow!C代码指令并将值推回处理器3DNow!寄存器.

到目前为止,我成功完成了前两个步骤(我从ExceptionInfo->ExtendedRegisters偏移量为32的字节数组中获取mmx寄存器值并使用浮点类型C指令进行计算),但我的问题是,无论我如何尝试更新MMX寄存器值的寄存器价值似乎保持不变.

假设我的_asm陈述可能是错误的,我还使用这样的简单语句进行了一些最小的测试:

_asm movq mm0 mm7
Run Code Online (Sandbox Code Playgroud)

执行此语句没有其他例外,但在检索MMX寄存器值时,我仍然发现原始值未更改.

如何使作业有效?

c++ windows assembly exception mmx

8
推荐指数
1
解决办法
247
查看次数

现在在 x86-64 上还值得使用 Quake 快速反平方根算法吗?

具体来说,这是我正在讨论的代码:

float InvSqrt(float x) {
  float xhalf = 0.5f*x;
  int i = *(int*)&x;        // warning: strict-aliasing UB, use memcpy instead
  i = 0x5f375a86- (i >> 1);
  x = *(float*)&i;          // same
  x = x*(1.5f-xhalf*x*x);
  return x;  
}
Run Code Online (Sandbox Code Playgroud)

我忘了我从哪里得到这个,但它显然比原来的 Quake III 算法(魔法常数略有不同)更好、更高效或更精确,但这个算法创建以来已经有 20 多年了,我只是想知道它是否是就性能而言,或者如果有一条指令已经在现代 x86-64 CPU 中实现了它,那么仍然值得使用它。

algorithm optimization x86-64 micro-optimization sqrt

8
推荐指数
1
解决办法
3763
查看次数

How to maximise instruction level parallelism of sqrt-heavy-loop on skylake architecture?

To introduced myself to x86 intrinsics (and cache friendliness to a lesser extent) I explicitly vectorized a bit of code I use for RBF (radial basis function) -based grid deformation. Having found vsqrtpd to be the major bottleneck I want to know if/how I can mask its latency further. This is the scalar computational kernel:

for(size_t i=0; i<nPt; ++i)
{
    double xi = X[i], yi = X[i+nPt], zi = X[i+2*nPt];

   for(size_t j=0; j<nCP; ++j)
   {
        // compute distance from i …
Run Code Online (Sandbox Code Playgroud)

c++ optimization x86 intrinsics avx

5
推荐指数
1
解决办法
112
查看次数

AVX2代码慢,没有AVX2

我一直在努力开始使用AVX2指令而运气不好(这个功能列表很有帮助).最后,我得到了我的第一个程序编译和做我想要的.我必须做的程序需要两个,u_char并且复合了两个.本质上,我使用它来解码存储在相机的u_char数组中的数据,但我认为这与此问题无关.

获得double两者的过程u_char是:

double result = sqrt(double((msb<<8) + lsb)/64);
Run Code Online (Sandbox Code Playgroud)

where msblsbu_char具有最高有效位(msb)的两个变量和要计算的较低有效位(lsb)double.数据被存储在表示行主矩阵,其中的阵列msblsb值编码列的i分别是在第二和第三行.我用和不用AVX2编码了这个:

void getData(u_char* data, size_t cols, std::vector<double>& info)
{
  info.resize(cols);
  for (size_t i = 0; i < cols; i++)
  {
    info[i] = sqrt(double((data[cols + i] << 8) + data[2 * cols + i]) / 64.0);
    ;
  }
}

void getDataAVX2(u_char* data, size_t cols, std::vector<double>& info)
{ …
Run Code Online (Sandbox Code Playgroud)

c++ performance x86 avx2

4
推荐指数
1
解决办法
662
查看次数

修复线裁剪算法的代码

中点细分算法[第93(104)页]的工作原理是将一条线分成更小的段,并测试每个段以查找它们是否在剪切区域的可见边界内。

在二分搜索算法中,我们找到中间元素,然后选择右侧或左侧。

但是,如下图所示,在第一次分割之后,我们发现这两个小节实际上都是有争议的。因此,它们都是进一步细分的候选者。所以,我们不能像二分查找那样进行。

在此输入图像描述

我正在使用迭代方法。但是,下面的代码不起作用:

    Line2d GetClippedLine()
    {
        Line2d clippingCandidate = this->line;

        std::vector<Line2d> lines = clippingCandidate.GetMidpointSubLines();

        while(lines[0] != lines[1])
        {
            lines = clippingCandidate.GetMidpointSubLines();

            Line2d one = lines[0];
            Line2d two = lines[1]; 

            if(one.IsClippingCandidate(rectangle))
            {
                clippingCandidate = one;
            }
            if(two.IsClippingCandidate(rectangle))
            {           
                clippingCandidate = two;
            }

            if(one.IsVisible(rectangle))
            {
                Coordinates2d::Draw(one, Yellow);
            }
            if(two.IsVisible(rectangle))
            {
                Coordinates2d::Draw(two, Yellow);
            }

            clippingCandidate.Show();
            //std::cout<<"++";
            //two.Show();
            std::cout<<"\n";
        }

        return clippingCandidate;
    }
Run Code Online (Sandbox Code Playgroud)

c++ algorithm graphics clipping

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

gcc 4.8 AVX 优化错误:额外的代码插入?

很高兴 gcc 编译器 4.8 带有带有 -Ofast 选项的 AVX 优化。但是,我发现了一个有趣但愚蠢的错误,它增加了不必要的额外计算。也许我错了,所以有人可以给我一个解释吗?

原来的C++源代码如下:

#define N 1000007

float a[N],b[N],c[N],d[N],e[N];

int main(int argc, char *argv[]){
    cout << a << ' ' << b << ' ' << c << endl;
    for(int x=0; x<N; ++x){
        c[x] = 1/sqrt((a[x]+b[x]-c[x])*d[x]/e[x]);
    }
    return  0;
}
Run Code Online (Sandbox Code Playgroud)

代码在 Ubuntu 14.04.3 x86_64 中使用 g++ 4.8.4 编译: g++ -mavx avx.cpp -masm=intel -c -g -Wa,-ahl=avx.asm -Ofast

汇编源代码如下:

  90                    .LVL10:
  91 006b C5FC2825              vmovaps ymm4, YMMWORD PTR .LC0[rip]
  91      00000000 
  92 0073 31C0                  xor     eax, …
Run Code Online (Sandbox Code Playgroud)

optimization gcc sse g++ avx

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

AVX 内在函数 _mm256_rsqrt_ps 的相对误差比根据内在函数指南应有的要大得多

英特尔内在函数指南指出,内在函数_mm256_rsqrt_ps的相对误差最多为1.5*2^-12。但是,当我将 的结果_mm256_rsqrt_ps与平方根倒数 ( 1.0 / sqrt(x)) 的标准 C++ 计算结果进行比较时,我得到的相对误差远大于1.5*2^-12

我使用以下程序来测试这一点:

#include <immintrin.h>
#include <iostream>
#include <math.h>

void test(float x) {
  float resP = _mm256_cvtss_f32(_mm256_rsqrt_ps(_mm256_set1_ps(x)));
  float res = 1.0 / sqrt(x);
  float relErr = fabs(resP - res) / res;
  std::cout << "x = " << x << std::endl;
  std::cout << "resP = " << resP << std::endl;
  std::cout << "res = " << res << std::endl;
  std::cout << "relErr = …
Run Code Online (Sandbox Code Playgroud)

c++ floating-point intrinsics avx

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

sqrtpd指令是否同时计算sqrt?

我正在学习 SIMD 内在函数和并行计算。我不确定Intel对x86指令的定义sqrtpd是否 表示将同时计算传递给它的两个数字的平方根:


对源操作数(第二个操作数)中的两个、四个或八个压缩双精度浮点值的平方根执行 SIMD 计算,并将压缩双精度浮点结果存储在目标操作数(第二个操作数)中第一个操作数)。


我知道它明确表示SIMD 计算,但这是否意味着对于此操作,将同时计算两个数字的根?

parallel-processing sse simd cpu-architecture intrinsics

0
推荐指数
1
解决办法
388
查看次数