相关疑难解决方法(0)

round()for C++中的float

我需要一个简单的浮点舍入函数,因此:

double round(double);

round(0.1) = 0
round(-0.1) = 0
round(-0.9) = -1
Run Code Online (Sandbox Code Playgroud)

我能找到ceil()floor()在math.h中-但不是round().

它是以另一个名称存在于标准C++库中,还是缺少?

c++ floating-point rounding

227
推荐指数
11
解决办法
36万
查看次数

如何使用SSE/AVX高效执行double/int64转换?

SSE2具有在单精度浮点数和32位整数之间转换向量的指令.

  • _mm_cvtps_epi32()
  • _mm_cvtepi32_ps()

但是没有双精度和64位整数的等价物.换句话说,他们失踪了:

  • _mm_cvtpd_epi64()
  • _mm_cvtepi64_pd()

似乎AVX也没有它们.

模拟这些内在函数的最有效方法是什么?

c++ floating-point sse simd avx

19
推荐指数
2
解决办法
2850
查看次数

使用SSE最快地实现指数函数

我正在寻找在SSE元素上运算的指数函数的近似值.即 - __m128 exp( __m128 x ).

我有一个快速但实际上准确度非常低的实现:

static inline __m128 FastExpSse(__m128 x)
{
    __m128 a = _mm_set1_ps(12102203.2f); // (1 << 23) / ln(2)
    __m128i b = _mm_set1_epi32(127 * (1 << 23) - 486411);
    __m128  m87 = _mm_set1_ps(-87);
    // fast exponential function, x should be in [-87, 87]
    __m128 mask = _mm_cmpge_ps(x, m87);

    __m128i tmp = _mm_add_epi32(_mm_cvtps_epi32(_mm_mul_ps(a, x)), b);
    return _mm_and_ps(_mm_castsi128_ps(tmp), mask);
}
Run Code Online (Sandbox Code Playgroud)

任何人都可以以更快的速度(或更快)获得更高精度的实现吗?

如果我用C风格写的话,我会很高兴的.

谢谢.

c optimization sse simd vectorization

13
推荐指数
3
解决办法
4246
查看次数

使用AVX最快的指数函数实现

我正在寻找在AVX元件(单精度浮点)上运行的指数函数的有效(快速)近似.即 - __m256 _mm256_exp_ps( __m256 x )没有SVML.

相对精度应该类似于~1e-6,或~20个尾数位(1 ^ 2 ^ 20).

如果用英特尔内在函数用C风格编写,我会很高兴.
代码应该是可移植的(Windows,macOS,Linux,MSVC,ICC,GCC等).


这类似于使用SSE的指数函数的最快实现,但是这个问题寻求非常快速且精度低(当前的答案提供了大约1e-3的精度).

此外,这个问题是寻找AVX/AVX2(和FMA).但请注意,这两个问题的答案很容易在SSE4 __m128或AVX2 之间移植__m256,因此未来读者应根据所需的精度/性能权衡进行选择.

x86 simd avx exponential avx2

7
推荐指数
3
解决办法
1944
查看次数

使用双精度运算的快速SSE低精度指数

我正在寻找快速SSE低精度(~1e-3)指数函数.

我遇到了这个很好的答案:

/* max. rel. error = 3.55959567e-2 on [-87.33654, 88.72283] */
__m128 FastExpSse (__m128 x)
{
    __m128 a = _mm_set1_ps (12102203.0f); /* (1 << 23) / log(2) */
    __m128i b = _mm_set1_epi32 (127 * (1 << 23) - 298765);
    __m128i t = _mm_add_epi32 (_mm_cvtps_epi32 (_mm_mul_ps (a, x)), b);
    return _mm_castsi128_ps (t);
}
Run Code Online (Sandbox Code Playgroud)

根据Nicol N. Schraudolph的工作:NN Schraudolph."指数函数的快速,紧凑近似." Neural Computation,11(4),1999年5月,pp.853-862.

现在我需要一个"双精度"版本:__m128d FastExpSSE (__m128d x).这是因为我不控制输入和输出精度,这恰好是双精度,并且两次转换double - > float,then float - > double占用了50%的CPU资源.

需要做哪些改变?

我天真地试过这个:

__m128i double_to_uint64(__m128d x) { …
Run Code Online (Sandbox Code Playgroud)

c++ precision sse simd exponential

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

在现代x86_64 CPU上,AVX/SSE指数需要多少个时钟周期?

在现代x86_64 CPU上,AVX/SSE指数需要多少个时钟周期?

我是这样的: pow(x, y) = exp(y*log(x))

即两者兼而有之exp(),log()AVX x86_64指令需要一定的已知周期数?

或者循环次数可能会根据指数级别而变化,是否有最大循环次数可以进行成本求幂?

c++ x86 sse x86-64 avx

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

SSE内在函数用于比较(_mm_cmpeq_ps)和赋值操作

我已经开始使用SSE优化我的代码.基本上它是一个光线跟踪器,通过在__m128数据类型x,y,z中存储坐标,一次处理4条光线(四条光线的坐标按轴分组).但是,我有一个分支语句,可以防止除以零,我似乎无法转换为SSE.连续这是:

const float d = wZ == -1.0f ? 1.0f/( 1.0f-wZ) : 1.0f/(1.0f+wZ);
Run Code Online (Sandbox Code Playgroud)

其中wZ是z坐标,需要对所有四条射线进行计算.

我怎么能把它翻译成SSE?

我一直在尝试使用SSE等于比较如下(现在wz属于__m128数据类型,包含四条光线中每条光线的z值):

_mm_cmpeq_ps(_mm_set1_ps(-1.0f) , wZ )
Run Code Online (Sandbox Code Playgroud)

然后使用它来识别wZ [x] = -1.0的情况,取这个情况的绝对值,然后继续计算正常.

但是,我在这方面没有取得多大成功.

c++ sse intrinsics

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