相关疑难解决方法(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万
查看次数

在什么情况下AVX2收集指令比单独加载数据更快?

我一直在研究使用AVX2指令集的新收集指令.具体来说,我决定对一个简单问题进行基准测试,其中一个浮点数组被置换并添加到另一个浮点数组中.在c中,这可以实现为

void vectortest(double * a,double * b,unsigned int * ind,unsigned int N)
{
    int i;
    for(i=0;i<N;++i)
    {
        a[i]+=b[ind[i]];
    }
}
Run Code Online (Sandbox Code Playgroud)

我用g ++ -O3 -march = native编译这个函数.现在,我以三种方式在汇编中实现它.为简单起见,我假设数组N的长度可以被4整除.简单的非矢量化实现:

align 4
global vectortest_asm
vectortest_asm:
        ;;  double * a = rdi                                                                                                                                                                                                                                   
        ;;  double * b = rsi                                                                                                                                                                                                                                   
        ;;  unsigned int * ind = rdx                                                                                                                                                                                                                           
        ;;  unsigned int N = rcx                                                                                                                                                                                                                               

        push rax
        xor rax,rax

loop:   sub rcx, 1
        mov eax, [rdx+rcx*4]    ;eax = ind[rcx]                                                                                                                                                                                                                
        vmovq xmm0, [rdi+rcx*8]         ;xmm0 = a[rcx]                                                                                                                                                                                                         
        vaddsd xmm0, [rsi+rax*8]        ;xmm1 …
Run Code Online (Sandbox Code Playgroud)

optimization assembly vectorization avx2

25
推荐指数
2
解决办法
4084
查看次数

用于SSE和AVX的SIMD数学库

我正在为SSE和AVX寻找SIMD数学库(最好是开源).我的意思是,例如,如果我有一个具有8个浮点值的AVX寄存器v,我希望sin(v)一次返回所有八个值的sin.

AMD有一个propreitery库,LibM http://developer.amd.com/tools/cpu-development/libm/,它有一些SIMD数学函数,但如果它检测到Intel CPU没有的FMA4,LibM只使用AVX.另外我不确定它是否完全使用AVX,因为所有的功能名称都以s4(d2)而不是s8(d4)结尾.它提供了比英特尔CPU上的标准数学库更好的性能,但它并没有好多少.

英特尔将SVML作为其C++编译器的一部分,但编译器套件在Windows上非常昂贵.此外,英特尔还削弱了非英特尔CPU上的库.

我找到了以下AVX库,http://software-lisc.fbk.eu/avx_mathfun/,它支持一些数学函数(exp,log,sin,cos和sincos).它为我提供了非常快的结果,比SVML更快,但我没有检查准确性.它仅适用于单个浮点,并且在Visual Studio中不起作用(尽管这很容易修复).它基于另一个SSE库.

有没有人有任何其他建议?

编辑:我发现一个SO线程有很多关于这个主题的答案 Vectorized Trig函数在C?

sse simd math.h avx

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

SSE2:双精度日志功能

我需要开源(没有许可限制)日志功能的实现,有签名的东西

__m128d _mm_log_pd(__m128d);
Run Code Online (Sandbox Code Playgroud)

它可以在英特尔短矢量数学库(ICC的一部分)中使用,但ICC既不是免费的也不是开源的.我正在寻找仅使用内在函数的实现.

它应该使用特殊的有理函数近似.我需要的东西几乎与cmath日志一样准确,比如9-10十进制数字,但更快.

c c++ optimization sse simd

10
推荐指数
2
解决办法
2526
查看次数

g ++ - 4.8中缺少AVX日志内在函数(_mm256_log_ps)?

我试图在我的代码中使用一些AVX内在函数,并遇到了对数内在函数的砖墙.

使用适用于Linux的英特尔intrinsics指南v3.0.1,我看到内在_mm256_log_ps(__m256)列为"immintrin.h"的一部分,并且在我当前的arch上也受支持.

但是,尝试编译这个简单的测试用例失败,并显示"错误:'_ mm256_log_ps'未在此范围内声明"

这个例子是用编译的 g++-4.8 -march=native -mavx test.cpp

#include <immintrin.h>
int main()
{
        __m256 i;
        _mm256_log_ps(i);
}
Run Code Online (Sandbox Code Playgroud)

我错过了一些基本的东西吗?某些内在函数是否不受g ++支持且仅在icc中可用?

已解决:此指令不是真正的内在指令,而是作为ICC的英特尔SVML的一部分实现的.

c++ g++ intrinsics avx

9
推荐指数
1
解决办法
3737
查看次数

C++中非常快速的近似Logarithm(自然日志)函数?

我们发现要替换的各种技巧std::sqrt(Timing Square Root)和一些std::exp(使用更快的指数近似),但我找不到任何可替代的东西std::log.

它是我程序中循环的一部分,它被多次调用,而exp和sqrt被优化,英特尔VTune现在建议我进行优化std::log,之后似乎只有我的设计选择才会受到限制.

现在我使用的第三阶泰勒近似ln(1+x)x之间-0.5+0.5(对于4%最大误差的情况下的%90)和回退到std::log否则.这让我加速了15%.

c++ math logarithm micro-optimization sqrt

7
推荐指数
1
解决办法
7488
查看次数

高效(在Ryzen上)将__m256的奇数元素提取到__m128中的方法?

是否有一种内在或另一种有效的方法将AVX寄存器的64位组件的高/低32位组件重新打包到SSE寄存器中?使用AVX2的解决方案还可以.

到目前为止,我正在使用以下代码,但是分析器说它在Ryzen 1800X上很慢:

// Global constant
const __m256i gHigh32Permute = _mm256_set_epi32(0, 0, 0, 0, 7, 5, 3, 1);

// ...

// function code
__m256i x = /* computed here */;
const __m128i high32 = _mm256_castsi256_si128(_mm256_permutevar8x32_epi32(x),
  gHigh32Permute); // This seems to take 3 cycles
Run Code Online (Sandbox Code Playgroud)

c++ sse x86-64 vectorization avx2

6
推荐指数
1
解决办法
273
查看次数

x86(带SSE2)和ARM(带vfpv4 NEON)上的尾数为11位的atan2近似

我正在尝试以尾数11位精度实现快速atan2(float)。atan2实现将用于图像处理。因此,最好使用SIMD指令(针对x86(带有SSE2)和ARM(带有vpfv4 NEON)的impl)实现。

现在,我使用chebyshev多项式逼近(https://jp.mathworks.com/help/fixedpoint/examples/calculate-fixed-point-arctangent.html)。

我愿意手动实现矢量化代码。我将使用SSE2(或更高版本)和NEON包装器库。我计划或尝试了这些实施选项

  • 向量化多项式逼近
    • 切比雪夫多项式(现已实现)
  • 标量查找表(+线性插值)
  • 向量化查找表(这可能吗?我对NEON不熟悉,所以我不知道NEON中的VGATHER之类的说明)
  • 向量化的CORDIC方法(这可能很慢,因为它需要进行12次以上的旋转迭代才能获得11位精度)

否则好主意?

sse simd neon

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

vgetmantps vs andpd 获取浮点数尾数的指令

对于 skylakex(agner 雾的说明表):

+-----------------------+-------------+-------------------+---------------------+----------------+---------+-----------------------+
|      Instruction      |  Operands   | µops fused domain | µops unfused domain | µops each port | Latency | Reciprocal throughput |
+-----------------------+-------------+-------------------+---------------------+----------------+---------+-----------------------+
| VGETMANTPS/PD         | v,v,v       |                 1 |                   1 | p01/05         |       4 | 0.5-1                 |
| AND/ANDN/OR/ XORPS/PD | x,x / y,y,y |                 1 |                   1 | p015           |       1 | 0.33                  |
+-----------------------+-------------+-------------------+---------------------+----------------+---------+-----------------------+
Run Code Online (Sandbox Code Playgroud)

这是否意味着使用位掩码和逻辑并获取浮点数的尾数比使用 vgetmantps 指令更快?

将数字从 float 传输到 int 再返回到 float 的延迟是多少?

floating-point performance x86 simd

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

AVX/SSE 将浮点符号掩码转换为 __m128i

我使用以下内容来提取 的符号位__mm128

const int sign_mask = _mm_movemask_ps(a);
Run Code Online (Sandbox Code Playgroud)

我现在想使用以下内容来混合两个向量:

v_add = _mm_blendv_ps(a, v_add_neg, _mm_castsi128_ps(v_mask));
Run Code Online (Sandbox Code Playgroud)

v_mask需要来自sign_mask但我找不到执行此操作的内在函数。

a该代码的目的是根据另一个向量的相应元素中的符号来更改向量元素的符号。

c sse simd intrinsics avx

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