相关疑难解决方法(0)

是否有可能在 AVX/SSE 中获得多个正弦?

我正在尝试编写一个 C++ 程序,它启动我在 x64 汇编程序中编写的函数。我想稍微加快速度(并利用 CPU 功能),所以我选择使用向量运算。

问题是,我必须将正弦乘以一个整数,所以我必须首先计算正弦。在 SSE/AVX 中可以做到这一点吗?我知道指令fsin,但它不仅在 FPU 中,而且它一次只计算 1 个正弦。所以我必须将它推入 FPU,调用fsin,将其从 FPU 弹出到内存,然后将其放入 AVX 寄存器。在我看来,这不值得这么麻烦。

windows trigonometry sse x86-64 avx

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

C++错误:未在此范围内声明'_mm_sin_ps'

我正在尝试使用不同的方法来将函数应用于数组.

为什么是https://software.intel.com/sites/landingpage/IntrinsicsGuide/#expand=3260,2124,4779,4779&cats=Trigonometry&text=_sin

_mm_sin_ps不知道我的范围,但是_mm_sqrt_ps

我怎么知道?并编译它没有错误.

#include <random>
#include <iostream>
#include <cmath>
#include <chrono>
#include <algorithm>
#include <valarray>
#include "immintrin.h"
#include <array>
int main()
{
    std::cout<<"start\n";
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_real_distribution<> dis(-1000, 1000);
    int N=100;
    while(N--)
    {   
        std::cout<<"\nN: "<<N;

    const int T1=4E6;
      { 
        int T=T1,T0=T1/4;
        std::array<float,T1> array;
        while(T--)
        {
            array[T]=dis(gen);
        }
        auto start_time = std::chrono::high_resolution_clock::now();
        auto it =array.begin();
        while(T0--)
        {
            __m128 X = _mm_loadu_ps(it);
            __m128 result = _mm_sin_ps(X);
            _mm_storeu_ps(it, result);
            it+=4;
        }
        auto time2=std::chrono::high_resolution_clock::now()-start_time;
            std::cout<<"\nintr1: "<<std::chrono::duration_cast<std::chrono::microseconds>(time2).count();
        }
  } …
Run Code Online (Sandbox Code Playgroud)

c++ optimization sse simd intrinsics

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

我如何使用SVML指令

我正在尝试exponential使用SIMD 计算函数。我发现了这个功能:https : //software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_exp_ps&expand=2136

我已经将其包含"immintrin.h"在代码中,并且我的cpu也有一个SSE标志。但是gcc在抱怨error: ‘_mm_exp_pd’ was not declared in this scope

如何检查SVML指令是否启用?

c++ x86 sse simd

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

逆立方根内在的 AVX-512 实现是 Microsoft 特有的吗?

我发现 MSVC 的 zmmintrin.h 副本定义了用于计算 __m512 32 位浮点向量和 __m512d 双向量的逆立方根的函数

 _mm512_invcbrt_ps();
 _mm512_invcbrt_pd();
Run Code Online (Sandbox Code Playgroud)

然而,这些函数在《Intel Intrinsics Guide》中没有出现: https: //software.intel.com/sites/landingpage/IntrinsicsGuide/

或者在英特尔更详细的开发指南中: https://software.intel.com/content/www/us/en/develop/documentation/cpp-compiler-developer-guide-and-reference/top/compiler-reference/intrinsics/英特尔高级向量扩展的内在函数-512-英特尔-avx-512-指令/算术运算的内在函数-1/短向量数学库-svml-操作的内在函数/内在函数- for-root-function-operations-512-bit.html

不过,它们似乎没有在微软的网站上列出,请参阅:https://learn.microsoft.com/en-us/cpp/intrinsics/compiler-intrinsics ?view=msvc-160

我知道平方根反比有序列内在函数:

_mm512_invsqrt_ps();
_mm512_invsqrt_pd();
Run Code Online (Sandbox Code Playgroud)

我知道AVX有逆立方根序列内在函数:

 _mm256_invcbrt_ps();
 _mm256_invcbrt_pd();
Run Code Online (Sandbox Code Playgroud)

_mm512_invcbrt_ps()也是如此;和_mm512_invcbrt_pd(); 微软特定的还是英特尔真的忘记记录它们的内在函数之一?!?

c++ simd intrinsics visual-c++ avx512

5
推荐指数
0
解决办法
261
查看次数

高效 10 次幂加倍

我必须多次将 10 提高到两倍的幂。

有没有比使用数学库更有效的方法来做到这一点pow(10,double)?如果重要的话,我的双打总是在 -5 到 -11 之间为负。

我假设 pow(double,double) 使用比 pow(10,double) 所需的更通用的算法,因此可能不是最快的方法。鉴于下面的一些答案,这可能是一个不正确的假设。

至于为什么,是对数插值。我有一个 x 和 y 值表。我的对象有一个已知的 x 值(几乎总是双精度值)。

double Dbeta(struct Data *diffusion, double per){
  double frac;
  while(per>diffusion->x[i]){
      i++;
  }
  frac = (per-diffusion->x[i-1])/(diffusion->x[i]-diffusion->x[i-1]);
  return pow(10,log10DB[i-1] + frac * (log10DB[i]-log10DB[i-1]));
}
Run Code Online (Sandbox Code Playgroud)

这个函数被调用了很多次。我被告知要研究分析,所以这就是我首先要做的。

我刚刚被告知我可以使用自然对数代替以 10 为底的,这显然是正确的。(我的愚蠢有时甚至让我自己感到惊讶。)

用自然对数替换所有内容后,一切都运行得更快了。通过分析(这是我今天学到的一个新词),我发现 39% 的代码都用在了 exp 函数中,所以对于那些想知道这部分是否真的阻碍了我的代码的人来说,它是。

c performance pow

3
推荐指数
1
解决办法
114
查看次数

标签 统计

c++ ×3

simd ×3

sse ×3

intrinsics ×2

avx ×1

avx512 ×1

c ×1

optimization ×1

performance ×1

pow ×1

trigonometry ×1

visual-c++ ×1

windows ×1

x86 ×1

x86-64 ×1