标签: fixed-point

定点算法值得我麻烦吗?

我正在研究一种应该实时运行的流体动力学Navier-Stokes求解器.因此,表现很重要.

现在,我正在研究一些紧密的循环,每个循环占执行时间的很大一部分:没有单一的瓶颈.这些循环中的大多数都进行了一些浮点运算,但是它们之间存在很多分支.

浮点运算主要限于加法,减法,乘法,除法和比较.所有这些都是使用32位浮点数完成的.我的目标平台是x86,至少有SSE1指令.(我在汇编器输出中验证了编译器确实生成了SSE指令.)

我正在使用的大多数浮点值具有相当小的上限,而接近零值的精度并不是非常重要.所以我想到了这样的想法:也许转换到定点算法会加快速度?我知道唯一可以确定的方法是测量它,可能需要数天,所以我想事先了解成功的可能性.

在Doom的时代,定点已经风靡一时,但我不确定它在2010年的位置.考虑到现在有多少芯片被用于浮点性能,是否有可能定点运算仍然存在给我一个显着的速度提升?有没有人有任何可能适用于我的情况的实际经验?

floating-point performance x86 fixed-point

12
推荐指数
2
解决办法
2760
查看次数

如何使用整数进行浮点计算

我有一个连接到主处理器的协处理器.某些浮点计算需要在协处理器中完成,但它不支持硬件浮点指令,并且仿真速度太慢.

现在,一种方法是让主处理器缩放浮点值,以便它们可以表示为整数,将它们发送给执行某些计算的协处理器,并在返回时缩减这些值.然而,这在大多数情况下都不会起作用,因为数字最终会变得太大或太小而不能超出这些整数的范围.所以我的问题是,正确做到这一点的最快方法是什么.

c embedded floating-point fixed-point

12
推荐指数
2
解决办法
7934
查看次数

如何在C++中优化简单的数值类型包装类?

我试图用C++实现一个定点类,但我遇到性能问题.我已经将问题简化为浮点类型的简单包装,它仍然很慢.我的问题是 - 为什么编译器无法完全优化它?

'float'版本比'Float'快50%.为什么?!

(我使用Visual C++ 2008,测试了所有可能的编译器选项,当然是Release配置).

请参阅以下代码:

#include <cstdio>
#include <cstdlib>
#include "Clock.h"      // just for measuring time

#define real Float      // Option 1
//#define real float        // Option 2

struct Float
{
private:
    float value;

public:
    Float(float value) : value(value) {}
    operator float() { return value; }

    Float& operator=(const Float& rhs)
    {
        value = rhs.value;
        return *this;
    }

    Float operator+ (const Float& rhs) const
    {
        return Float( value + rhs.value );
    }

    Float operator- (const Float& rhs) const …
Run Code Online (Sandbox Code Playgroud)

c++ optimization performance fixed-point

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

如何提高小值的定点平方根

我正在使用Dobb博士的文章" 使用定点运算优化数学密集型应用 "中描述的Anthony Williams的定点库,使用Rhumb Line方法计算两个地理点之间的距离.

当点之间的距离很大(大于几公里)时,这种方法运行良好,但在较小距离处则非常差.最坏的情况是当两个点相等或接近相等时,结果是194米的距离,而我需要距离> = 1米时至少1米的精度.

通过与双精度浮点实现的比较,我将问题定位到fixed::sqrt()函数,该函数在小值时表现不佳:

x       std::sqrt(x)    fixed::sqrt(x)  error
----------------------------------------------------
0       0               3.05176e-005    3.05176e-005
1e-005  0.00316228      0.00316334      1.06005e-006
2e-005  0.00447214      0.00447226      1.19752e-007
3e-005  0.00547723      0.0054779       6.72248e-007
4e-005  0.00632456      0.00632477      2.12746e-007
5e-005  0.00707107      0.0070715       4.27244e-007
6e-005  0.00774597      0.0077467       7.2978e-007
7e-005  0.0083666       0.00836658      1.54875e-008
8e-005  0.00894427      0.00894427      1.085e-009
Run Code Online (Sandbox Code Playgroud)

fixed::sqrt(0)通过将其视为一种特殊情况来校正结果是微不足道的,但是这不能解决小的非零距离问题,其中误差从194米开始并且随着距离的增加趋于零.我可能至少需要将精度提高到零的顺序.

fixed::sqrt()algorithim简要上面链接的文章第4页的解释,但我在努力遵循它更不用说确定它是否能够改善它.该功能的代码如下:

fixed fixed::sqrt() const
{
    unsigned const max_shift=62;
    uint64_t a_squared=1LL<<max_shift;
    unsigned b_shift=(max_shift+fixed_resolution_shift)/2;
    uint64_t a=1LL<<b_shift;

    uint64_t x=m_nVal;

    while(b_shift && a_squared>x)
    {
        a>>=1;
        a_squared>>=2; …
Run Code Online (Sandbox Code Playgroud)

c++ embedded fixed-point sqrt square-root

11
推荐指数
2
解决办法
3135
查看次数

如何使用32位除法指令执行64位除法?

这是(AFAIK)这个一般主题中的一个具体问题.

情况如下:

我有一个基于32位RISC微控制器(NEC V810的变体)的嵌入式系统(视频游戏控制台).我想写一个定点数学库.我读过这篇文章,但随附的源代码是用386汇编编写的,所以它既不能直接使用也不能轻易修改.

V810有内置的整数乘法/除法,但我想使用上面文章中提到的18.14格式.这需要将64位int除以32位int,而V810仅执行(有符号或无符号)32位/ 32位除法(产生32位商和32位余数).

所以,我的问题是:如何使用32位/ 32位模拟64位/ 32位除法(以允许红移的预移位)?或者,从另一种方式来看问题,使用标准的32位算术/逻辑运算将18.14定点除以另一种定义的最佳方法是什么?("最好"意味着最快,最小或两者兼而有之).

代数,(V810)汇编和伪代码都很好.我将从C调用代码.

提前致谢!

编辑:不知怎的,我错过了这个问题 ...但是,它仍然需要一些修改才能超级高效(它必须比v810提供的浮点div快,尽管它可能已经......),因此,我可以随意为我工作,以换取声望点;)(当然,我的图书馆文档中也有用).

math assembly fixed-point cpu-architecture integer-division

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

为什么C99中不包含定点类型?

值得庆幸的是,complex类型修饰符被引入C99标准.我不明白为什么决定省略对定点运算的支持(特别是支持分数类型,如1.15 {signed}或0.32 {unsigned}),这些类型对于DSP编程是如此重要?

GCC是否通过扩展支持这些?

c gcc fixed-point c99

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

为什么以这种方式执行乘法?

我遇到过这个函数:

static inline INT32 MPY48SR(INT16 o16, INT32 o32)
{
    UINT32   Temp0;
    INT32    Temp1;
    // A1. get the lower 16 bits of the 32-bit param
    // A2. multiply them with the 16-bit param
    // A3. add 16384 (TODO: why?)
    // A4. bitshift to the right by 15 (TODO: why 15?)
    Temp0 = (((UINT16)o32 * o16) + 0x4000) >> 15;
    // B1. Get the higher 16 bits of the 32-bit param
    // B2. Multiply them with the 16-bit param
    Temp1 = (INT16)(o32 …
Run Code Online (Sandbox Code Playgroud)

c++ fixed-point multiplication

9
推荐指数
2
解决办法
757
查看次数

具有C或D的浮点语义的整数类型

我正在寻找CD的现有实现,或者实现具有浮点语义的实现,有符号和/或无符号整数类型的建议.

也就是说,这表现为浮点类型整型运算做什么时候:溢出产生无穷大(-infinity的签署下溢),而不是缠绕或具有不确定的行为,不确定的操作产生的NaN

本质上是一个浮点版本,其中可呈现数字的分布均匀地落在数字线上,而不是在0附近聚合.

此外,所有操作都应该是确定性的 ; 任何给定的二进制补码32位架构应该为相同的计算产生完全相同的结果,无论其实现如何(而浮点可能,并且通常会产生稍微不同的结果).

最后,性能是一个问题,让我担心潜在的"bignum"(任意精度)解决方案.

另请参见:定点饱和算术.

c floating-point int d fixed-point

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

所有C++定点操作都是确定性的吗?

我正在用C++编写一个小型RTS引擎,并希望使用锁步同步.

由于浮点确定性是我甚至无法实现的,我必须使用定点数学.

确定性地(在不同的编译器和cpus上)是如何定义无符号整数的典型操作的?

我对分工特别感兴趣,因为这会导致四舍五入.

c++ fixed-point

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

负数的定点乘法

我有以下方法以固定点19.13格式乘以两个32位数 .但我认为这种方法存在问题:

1.5f向上舍入到2.0f,而-1.5f向上舍入到-1.0f.

在我看来-1.5应该向下舍入到-2.0f.

首先,当前的舍入是否有意义,如果没有,我怎样才能将其更改为更一致?

static OPJ_INT32 opj_int_fix_mul(OPJ_INT32 a, OPJ_INT32 b) {
    OPJ_INT64 temp = (OPJ_INT64) a * (OPJ_INT64) b ;
   temp += 4096;
   assert((temp >> 13) <= (OPJ_INT64)0x7FFFFFFF);
   assert((temp >> 13) >= (-(OPJ_INT64)0x7FFFFFFF - (OPJ_INT64)1));
   return (OPJ_INT32) (temp >> 13);
}
Run Code Online (Sandbox Code Playgroud)

fixed-point

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