我需要一个简单的浮点舍入函数,因此:
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++库中,还是缺少?
我正在寻找在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风格写的话,我会很高兴的.
谢谢.
有一种快速的方法可以2.0达到一些浮点数x吗?我的意思是比pow(2.0, x)使用AVX2 更好地矢量化的东西.
整数的对应物是1<<n,但它n仅适用于整数.
根据https://sourceware.org/glibc/wiki/libmvec GCC 具有数学函数的矢量实现。它们可以被编译器用于优化,可以在这个例子中看到: https: //godbolt.org/g/IcxtVi,编译器使用一些损坏的正弦函数并一次对 4 个双精度数进行操作
我知道如果我需要数学函数,可以使用 SIMD 数学库,但我仍然感兴趣是否有一种方法可以使用__m256d某种内在函数或任何其他方式手动调用 GCC 中已经存在的向量化数学函数?
下面是我想要转换的代码:该double版本的VDT的帕德精通fast_ex()约(这里的老回购资源):
inline double fast_exp(double initial_x){
double x = initial_x;
double px=details::fpfloor(details::LOG2E * x +0.5);
const int32_t n = int32_t(px);
x -= px * 6.93145751953125E-1;
x -= px * 1.42860682030941723212E-6;
const double xx = x * x;
// px = x * P(x**2).
px = details::PX1exp;
px *= xx;
px += details::PX2exp;
px *= xx;
px += details::PX3exp;
px *= x;
// Evaluate Q(x**2).
double qx = details::QX1exp;
qx *= xx;
qx += details::QX2exp;
qx …Run Code Online (Sandbox Code Playgroud) 作为一个OpenMP&Rcpp性能测试,我想检查我使用最简单和简单的Rcpp+ OpenMP实现来计算R中Mandelbrot集的速度.目前我所做的是:
#include <Rcpp.h>
#include <omp.h>
// [[Rcpp::plugins(openmp)]]
using namespace Rcpp;
// [[Rcpp::export]]
Rcpp::NumericMatrix mandelRcpp(const double x_min, const double x_max, const double y_min, const double y_max,
const int res_x, const int res_y, const int nb_iter) {
Rcpp::NumericMatrix ret(res_x, res_y);
double x_step = (x_max - x_min) / res_x;
double y_step = (y_max - y_min) / res_y;
int r,c;
#pragma omp parallel for default(shared) private(c) schedule(dynamic,1)
for (r = 0; r < res_y; r++) { …Run Code Online (Sandbox Code Playgroud) 我正在使用大型数组测试 Linux 的 ac 代码以测量线程性能,当线程增加到最大内核(Intel 4770 为 8 个)时,应用程序可以很好地扩展,但这仅适用于我的代码的纯数学部分。
如果我为结果数组添加 printf 部分,那么即使重定向到文件,时间也会变得太大,从几秒到几分钟,而当 printf 这些数组应该只添加几秒时。
代码:
(gcc 7.5.0-Ubuntu 18.04)
没有 printf 循环:
gcc -O3 -m64 exp_multi.c -pthread -lm
Run Code Online (Sandbox Code Playgroud)
使用 printf 循环:
gcc -DPRINT_ARRAY -O3 -m64 exp_multi.c -pthread -lm
Run Code Online (Sandbox Code Playgroud)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#define MAXSIZE 1000000
#define REIT 100000
#define XXX -5
#define num_threads 8
static double xv[MAXSIZE];
static double yv[MAXSIZE];
/* gcc -O3 -m64 exp_multi.c -pthread -lm */
void* run(void *received_Val){
int single_val = *((int *) received_Val); …Run Code Online (Sandbox Code Playgroud) 我编写了一些用于处理单精度浮点计算 SIMD 内在函数的优化。
有时,双精度指令比任何单精度指令pd更容易满足我的要求。ps
示例1:
我有指针float prt * ,它指向浮点数块: f0 f1 f2 f3 等。
我想用 [ f0, f1, f0, f1, f0, f1, f0, f1 ] 加载 __m256 值。我没有找到__m256数据类型的 64 位广播。我可以_mm256_broadcast_sd在花车上使用吗?
float* ptr = ...; // pointer to some memory chunk aligned to 4 bytes
__m256 vat = _mm256_castpd_ps( _mm256_broadcast_sd( ( double* )ptr ) );
Run Code Online (Sandbox Code Playgroud)
示例2:
我有 __m256 值 [f0, f1, f2, f3, f4, f5, f6, f7]。我可以使用像 _mm256_srl_epi32 这样的移位指令,它以 __m256i 值作为参数来使用我的 __m256 值进行操作吗? …
simd ×4
c ×3
c++ ×3
avx ×2
intrinsics ×2
sse ×2
exp ×1
gcc ×1
mandelbrot ×1
openmp ×1
optimization ×1
performance ×1
pow ×1
pthreads ×1
rcpp ×1
rounding ×1
sse2 ×1
x86-64 ×1