小编nju*_*ffa的帖子

使用标准C数学库实现sinpi()和cospi()

函数sinpi(x)计算sin(?x),函数cospi(x)计算cos(?x),其中乘以?在函数内部是隐式的。这些功能最初是由Sun Microsystems在1980年代末期扩展为C标准数学库的。IEEE标准754™-2008指定的等价的功能sinPicosPi在第9。

有许多计算会自然产生sin(?x)和cos(?x)。一个非常简单的例子是Box-Muller变换(GEP Box和Mervin E. Muller,“关于随机正态偏差的生成的注释”。《数学统计》,第29卷,第2期,第610-611 页) ),则给定两个独立的随机变量U?和你?分布均匀,产生独立的随机变量Z?和Z?标准正态分布:

Z? = ?(-2 ln U?) cos (2 ? U?)
Z? = ?(-2 ln U?) sin (2 ? U?)
Run Code Online (Sandbox Code Playgroud)

另一个示例是度数参数的正弦和余弦计算,如使用Haversine公式的大圆距离计算:

Z? = ?(-2 ln U?) cos (2 ? U?)
Z? = ?(-2 ln U?) sin (2 ? U?)
Run Code Online (Sandbox Code Playgroud)

对于C ++,Boost库提供sin_picos_pi,某些供应商提供sinpicospi功能作为系统库中的扩展。例如,苹果增加__sinpi__cospi和相应的单精度版本__sinpif__cospif到iOS 7和OS X 10.9(介绍,幻灯片101)。但是对于许多其他平台,没有C程序可以轻易访问的实现。 …

c floating-point trigonometry math.h

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

GPU在OpenCV 3.0上的功能在哪里?

据我所知,在OpenCV 3.0中,模块GPU已被模块CUDA取代,或者更好地将其拆分为多个模块.

所以cv::gpu::GpuMat已被取代cv::cuda::GpuMat,很好.

但功能怎么样?

例如,移动到以下位置:

cv::gpu::GaussianBlurr ?
cv::gpu::Stream stream;
stream.enqueueConvert(...)
Run Code Online (Sandbox Code Playgroud)

显然他们不在cuda模块下(例如,没有cv::cuda::GaussianBlurr).哪些功能可以在OpenCV 3.0中找到?

c++ opencv cuda

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

互补错误函数erfcf()的可矢量化实现

互补误差函数erfc是与标准正态分布密切相关的特殊函数.它经常用于统计学和自然科学(例如扩散问题),其中需要考虑该分布的"尾部",因此使用误差函数erf是不合适的.

互补误差函数是在ISO C99标准数学库提供作为功能erfcf,erfcerfcl; 这些随后也被采用到ISO C++中.因此,源代码可以很容易地在该库的开源实现中找到,例如在glibc中.

然而,许多现有的实现本质上是标量的,而现代处理器硬件是面向SIMD的(显式地,如在x86 CPU中,或隐式地,如在GPU中).出于性能原因,因此非常需要可矢量化的实现.这意味着需要避免分支,除非作为选择分配的一部分.同样,没有指出表的广泛使用,因为并行查找通常是低效的.

如何构建单精度函数的高效矢量化实现erfcf()?测量的准确度ulp应与glibc的标量实现大致相同,其最大误差为3.12575 ulps(通过详尽测试确定).可以假设融合乘法加法(FMA)的可用性,因为此时所有主要处理器架构(CPU和GPU)都提供它.处理浮点状态标志时errno可以忽略,非正规,无穷大和NaN应根据ISO 75的IEEE 754绑定进行处理.

c algorithm math floating-point

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

如何并行删除数组中的零值

如何使用CUDA并行地从数组中有效地删除零值.有关零值数量的信息可以提前获得,这可以简化此任务.

在复制到结果数组时,数字在源数组中保持有序排列非常重要.


例:

该数组将例如包含以下值:[0,0,19,7,0,3,5,0,0,1]以及5个值为零的附加信息.然后,期望的最终结果将是包含以下内容的另一个数组:[19,7,3,5,1]

c++ arrays cuda thrust

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

从log1pf()计算asinhf()的最准确方法是什么?

反双曲函数asinh()与自然对数密切相关.我试图asinh()从C99标准数学函数中确定最准确的计算方法log1p().为了便于实验,我现在限制自己使用IEEE-754单精度计算,我正在考虑asinhf()log1pf().我打算重新使用双精度计算,即完全相同的算法asinh()log1p(),后来.

我的主要目标是最小化ulp错误,次要目标是最小化错误舍入结果的数量,在改进代码最多比下面发布的版本最低的约束下.任何提高准确度的改进,比如说0.2 ulp,都是值得欢迎的.添加几个FMA(融合乘法 - 加法)会很好,另一方面我希望有人可以找到一个采用快速rsqrtf()(倒数平方根)的解决方案.

生成的C99代码应该适用于矢量化,可能是通过一些简单的直接转换.所有中间计算必须以函数参数和结果的精度发生,因为任何切换到更高精度可能会产生严重的负面性能影响.代码必须在IEEE-754非正常支持和FTZ(刷新到零)模式下正常工作.

到目前为止,我已经确定了以下两个候选实现.请注意,可以通过单次调用将代码轻松转换为无分支矢量化版本log1pf(),但在此阶段我还没有这样做以避免不必要的混淆.

/* for a >= 0, asinh(a) = log (a + sqrt (a*a+1))
                        = log1p (a + (sqrt (a*a+1) - 1))
                        = log1p (a + sqrt1pm1 (a*a))
                        = log1p (a + (a*a / (1 + sqrt(a*a + 1))))
                        = log1p (a + a * (a / (1 + sqrt(a*a + 1))))
                        = log1p (fma …
Run Code Online (Sandbox Code Playgroud)

c math floating-point floating-accuracy

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

在GPU上使用2个FP32仿真FP64

如果要模拟具有两个单精度浮点的双精度浮点,那么性能会是什么样的,并且可以做得好吗?

目前,Nvidia正在为双精度特斯拉卡充电,这使得您可以获得单精度性能的三分之一(值得注意的是Titan/Titan Black除外).

如果要使用具有gimped双精度的Geforce GPU并使用2个单精度浮点模拟双精度,性能会是什么样的?

floating-point double cuda

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

高效忠实地实现错误函数erff()

误差函数与标准正态分布密切相关,并且经常出现在自然科学以及其他领域.例如,它在定价选项时用于财务.虽然第一至ISO C99,并随后加入到C++中的函数的形式为它支持erf(),erff(),它是直到最近不在从至少一个流行的C/C +工具链.许多项目仍然使用他们自己的错误函数实现,通常基于旧文献的近似,例如Abramowitz和Stegun,后者又回到

Cecil Hastings Jr,"数字计算机的近似".普林斯顿大学出版社,1955年

在现代计算中,超越函数的忠实圆形实现通常被视为数学库的最低准确度标准; 这样的标准仍然允许高性能实现.当函数返回最大误差小于1 ulp的结果与整个输入域中的数学值相比时,函数被称为忠实舍入.当使用IEEE-754单精度操作实现时,较早发布的算法不能提供忠实的圆形结果.

现代计算机硬件提供称为融合乘法 - 加法(或简称FMA)的浮点运算,它计算浮点乘法,然后进行相关的浮点加法,以便在加法中使用完整的未接地产品,并且只有单个舍入发生在操作结束时.IBM于1990年推出的这种融合操作在许多计算中提供了更高的准确性和更高的性能.它可用于当今最流行的两种CPU架构(ARM和x86)以及GPU.它已通过fmaf()fmaf()函数在C和C++中公开.

假设FMA本身是由硬件支持的,那么如何构建一个erff()忠实舍入且高效的单精度误差函数呢?优选地,代码应该是可矢量化的,可能在次要代码修改之后.

c floating-point

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

32 位平台上的无符号 64x64->128 位整数乘法

在探索活动的背景下,我开始研究 32 位平台的整数和定点算术构建块。我的主要目标是 ARM32(特别是 ARM32 armv7),同时关注 RISC-V32,我预计 RISC-V32 在嵌入式领域的重要性会不断提高。我选择检查的第一个示例构建块是无符号 64x64->128 位整数乘法。本网站上有关此构建块的其他问题未提供 32 位平台的详细介绍。

在过去的三十年里,我多次实现了这个和其他算术构建块,但总是使用汇编语言,用于各种体系结构。然而,此时我的希望和愿望是这些可以直接用 ISO-C 进行编程,而不使用内在函数。理想情况下,单一版本的 C 代码将生成跨架构的良好机器代码。我知道操纵 HLL 代码来控制机器代码的方法通常很脆弱,但希望处理器架构和工具链已经足够成熟,使之变得可行。

汇编语言实现中使用的一些方法不太适合移植到 C。在下面的示例代码中,我选择了似乎适合 HLL 实现的六个变体。除了生成所有变体所共有的部分积之外,两种基本方法是: (1) 使用 64 位算术对部分积求和,让编译器负责 32 位半部分之间的进位传播。在这种情况下,有多种选择对部分乘积求和的顺序。(2) 使用32位运算进行求和,直接模拟进位标志。在这种情况下,我们可以选择在加法之后 ( a = a + b; carry = a < b;) 或加法之前 ( carry = ~a < b; a = a + b;) 生成进位。下面的变体 1 到 3 属于前一类,变体 5 和 6 属于后者。

Compiler Explorer中,我专注于感兴趣平台的工具链 gcc 12.2 和 clang 15.0。我用 编译-O3。总体发现是,平均而言,clang 生成的代码比 gcc …

c arm micro-optimization bigint riscv32

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

对于CUDA,是否可以保证三元运营商可以避免分支差异?

我已经阅读了很多关于CUDA分支差异的线索,告诉我使用三元运算符比if/else语句更好,因为三元运算符不会导致分支分歧.我想知道,对于以下代码:

foo = (a > b) ? (bar(a)) : (b);
Run Code Online (Sandbox Code Playgroud)

如果bar是另一个函数或更复杂的语句,那么是否仍然没有分支差异?

cuda

5
推荐指数
2
解决办法
1628
查看次数

精确计算定标互补误差函数erfcx()

通常用表示的(指数)缩放的互补误差函数erfcx在数学上定义为erfcx(x):= e x 2 erfc(x)。它经常发生在物理和化学扩散问题中。虽然某些数学环境(例如MATLABGNU Octave)提供了此功能,但C标准数学库中却没有,该函数仅提供erf()erfc()

尽管可以erfcx()直接基于数学定义实现自己的方法,但这仅在有限的输入域上起作用,因为例如在erfc()中等半自变量的正半平面下溢中,而exp()此问题中指出,例如上溢。

如要与C一起使用,可以对某些erfcx()开源实现进行改编,例如Faadeeva软件包中的一个,如对此问题的回答所指出的。但是,这些实现通常不能为给定的浮点格式提供完整的准确性。例如,使用2 32个测试向量进行的测试显示,erfcx()由Faadeeva软件包提供的最大误差在正半平面中为8.41 ulps,在负半平面中为511.68 ulps。

准确实现的合理范围为4 ulps,对应于Intel Vector Math库的LA概要文件中数学函数的精确范围,我发现这对于要求两者均满足的非平凡数学函数实现而言是合理范围良好的精度和良好的性能。

怎么可能erfcx(),以及相应的单精度版本erfcxf(),准确地实施,而仅使用C标准数学库,以及无需外部库?我们可以假定C的floatnad double类型映射到IEEE 754-2008 binary32binary64浮点类型。可以假定对融合乘法加法运算(FMA)的硬件支持,因为此时所有主要处理器体系结构都支持该功能。

c math floating-point floating-accuracy

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