相关疑难解决方法(0)

常数0.0039215689代表什么?

我一直看到这个常量弹出各种图形头文件

0.0039215689
Run Code Online (Sandbox Code Playgroud)

它似乎与颜色有关吗?

这是Google的第一个热门话题:

void RDP_G_SETFOGCOLOR(void)
{
    Gfx.FogColor.R = _SHIFTR(w1, 24, 8) * 0.0039215689f;
    Gfx.FogColor.G = _SHIFTR(w1, 16, 8) * 0.0039215689f;
    Gfx.FogColor.B = _SHIFTR(w1, 8, 8) * 0.0039215689f;
    Gfx.FogColor.A = _SHIFTR(w1, 0, 8) * 0.0039215689f;
}

void RDP_G_SETBLENDCOLOR(void)
{
    Gfx.BlendColor.R = _SHIFTR(w1, 24, 8) * 0.0039215689f;
    Gfx.BlendColor.G = _SHIFTR(w1, 16, 8) * 0.0039215689f;
    Gfx.BlendColor.B = _SHIFTR(w1, 8, 8) * 0.0039215689f;
    Gfx.BlendColor.A = _SHIFTR(w1, 0, 8) * 0.0039215689f;

    if(OpenGL.Ext_FragmentProgram && (System.Options & BRDP_COMBINER)) {
        glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, Gfx.BlendColor.R, …
Run Code Online (Sandbox Code Playgroud)

c floating-point constants magic-numbers

308
推荐指数
2
解决办法
2万
查看次数

gcc的ffast-math实际上做了什么?

我理解gcc的--ffast-math标志可以大大提高浮动操作的速度,并超出IEEE标准,但我似乎无法找到有关它正在发生的事情的信息.任何人都可以解释一些细节,并可能给出一个明确的例子,说明如果标志开启或关闭会有什么变化?

我确实尝试过挖掘SO以寻找类似的问题,但却找不到任何解释ffast-math工作原理的东西.

math floating-point performance gcc fast-math

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

浮点除法与浮点乘法

通过编码是否有任何(非微优化)性能增益

float f1 = 200f / 2
Run Code Online (Sandbox Code Playgroud)

在比较中

float f2 = 200f * 0.5
Run Code Online (Sandbox Code Playgroud)

几年前我的一位教授告诉我,浮点除法比浮点乘法慢,但没有详细说明原因.

这句话适用于现代PC架构吗?

UPDATE1

关于评论,请同时考虑这个案例:

float f1;
float f2 = 2
float f3 = 3;
for( i =0 ; i < 1e8; i++)
{
  f1 = (i * f2 + i / f3) * 0.5; //or divide by 2.0f, respectively
}
Run Code Online (Sandbox Code Playgroud)

更新2 从评论中引用:

[我想]知道什么是算法/架构要求导致>除法在硬件上比复制要复杂得多

c++ floating-point micro-optimization

67
推荐指数
5
解决办法
5万
查看次数

编译器优化可能会导致整数溢出。可以吗?

我有一个int x。为简单起见,假设ints 占据范围 -2^31 到 2^31-1。我想计算2*x-1. 我允许x为任何值 0 <= x<= 2^30。如果我计算 2*(2^30),我会得到 2^31,这是整数溢出。

一种解决方案是计算2*(x-1)+1. 比我想要的多了一项减法,但这不应该溢出。但是,编译器会将其优化为2*x-1. 这是源代码的问题吗?这是可执行文件的问题吗?

是 Godbolt 的输出2*x-1

func(int):                               # @func(int)
        lea     eax, [rdi + rdi]
        dec     eax
        ret
Run Code Online (Sandbox Code Playgroud)

是 Godbolt 的输出2*(x-1)+1

func(int):                               # @func(int)
        lea     eax, [rdi + rdi]
        dec     eax
        ret
Run Code Online (Sandbox Code Playgroud)

c++ integer-overflow compiler-optimization undefined-behavior integer-arithmetic

64
推荐指数
4
解决办法
7744
查看次数

如何在SSE/AVX中使用融合乘法 - 加法(FMA)指令

我已经了解到一些Intel/AMD CPU可以同时进行多次复用并添加SSE/AVX:
每个周期的FLOPS用于沙桥和haswell SSE2/AVX/AVX2.

我想知道如何在代码中做到最好,我也想知道它是如何在CPU内部完成的.我的意思是超标量架构.假设我想做一个很长的总和,如下面的SSE:

//sum = a1*b1 + a2*b2 + a3*b3 +... where a is a scalar and b is a SIMD vector (e.g. from matrix multiplication)
sum = _mm_set1_ps(0.0f);
a1  = _mm_set1_ps(a[0]); 
b1  = _mm_load_ps(&b[0]);
sum = _mm_add_ps(sum, _mm_mul_ps(a1, b1));

a2  = _mm_set1_ps(a[1]); 
b2  = _mm_load_ps(&b[4]);
sum = _mm_add_ps(sum, _mm_mul_ps(a2, b2));

a3  = _mm_set1_ps(a[2]); 
b3  = _mm_load_ps(&b[8]);
sum = _mm_add_ps(sum, _mm_mul_ps(a3, b3));
...
Run Code Online (Sandbox Code Playgroud)

我的问题是如何将其转换为同时乘法并添加?数据可以依赖吗?我的意思是CPU可以_mm_add_ps(sum, _mm_mul_ps(a1, b1))同时执行还是在乘法中使用的寄存器和add必须是独立的?

最后,这如何适用于FMA(与Haswell)?是_mm_add_ps(sum, _mm_mul_ps(a1, b1))自动转换为单个FMA指令还是微操作?

c sse cpu-architecture avx fma

40
推荐指数
2
解决办法
3万
查看次数

在C++中最快的正弦,余弦和平方根的实现(不需要太精确)

我正在谷歌搜索过去一小时的问题,但只有泰勒系列或一些示例代码的要点太慢或根本不编译.好吧,我发现谷歌的答案大多是"Google it,它已经被问到了",但遗憾的是它不是 ......

我在低端Pentium 4上分析我的游戏,发现大约85%的执行时间浪费在计算窦,cosinus和平方根(来自Visual Studio中的标准C++库)上,这似乎与CPU密切相关(在我的I7上,相同的功能只有5%的执行时间,并且游戏更快了waaaaaaaaaa).我不能优化这三个函数,也不能在一次传递中计算正弦和余弦(相互依赖),但我不需要太精确的模拟结果,所以我可以使用更快的逼近.

那么,问题是:在C++中计算float的正弦,余弦和平方根的最快方法是什么?

编辑 查找表更加痛苦,因为在现代CPU上产生的Cache Miss比Taylor系列更昂贵.这些天CPU很快,而缓存则不然.

我犯了一个错误,我虽然需要为Taylor系列计算几个阶乘,我现在看到它们可以实现为常量.

所以更新的问题是:对于平方根还有任何快速优化吗?

EDIT2

我使用平方根计算距离,而不是规范化 - 不能使用快速反平方根算法(如评论中所指出:http://en.wikipedia.org/wiki/Fast_inverse_square_root

EDIT3

我也无法在平方距离上操作,我需要精确的距离进行计算

c++ math optimization trigonometry

34
推荐指数
10
解决办法
6万
查看次数

为什么x**3比x*x*x慢?

在NumPy中,x*x*x比x**3或甚至np.power(x,3)快一个数量级.

x = np.random.rand(1e6)
%timeit x**3
100 loops, best of 3: 7.07 ms per loop

%timeit x*x*x
10000 loops, best of 3: 163 µs per loop

%timeit np.power(x, 3)
100 loops, best of 3: 7.15 ms per loop
Run Code Online (Sandbox Code Playgroud)

关于为什么会发生这种行为的任何想法?据我所知,三个产生相同的输出(用np.allclose检查).

python numpy

25
推荐指数
2
解决办法
3848
查看次数

如果 C 编译器无法证明缺少 UB,为什么要禁止优化?

如果 C 程序有未定义的行为,任何事情都可能发生。因此编译器可能会假设任何给定的程序不包含 UB。因此,假设我们的程序包含以下内容:

\n
x += 5;\n/* Do something else without x in the meantime. */ \nx += 7;\n
Run Code Online (Sandbox Code Playgroud)\n

当然,这可以优化为

\n
/* Do something without x. */\nx += 12;\n
Run Code Online (Sandbox Code Playgroud)\n

或类似的其他方式。

\n

如果 x 具有类型,unsigned int则上述程序中不可能出现 UB。另一方面,如果 x 有类型signed int,则有可能溢出,从而产生 UB。由于编译器可能会假设我们的程序不包含UB,因此我们可以进行与上面相同的优化。事实上,在这种情况下,编译器甚至可以假设x - 12 <= MAX_INT.

\n

然而,这似乎与 Jens Gustedt 著名的“Modern C”(第 42 页)相矛盾:

\n
\n

但这样的优化也可以被禁止,因为编译器无法证明某个操作不会强制程序终止。在我们的示例中,很大程度上取决于 x 的类型。如果 x 的当前值可能接近类型的上限,则看似无辜的操作 x += 7 可能会产生溢出。此类溢出根据类型的不同而有不同的处理方式。正如我们所看到的,无符号类型的溢出不是问题,并且压缩运算的结果将始终与两个单独的结果一致。对于其他类型,例如有符号整数类型(signed)和浮点类型(double),溢出可能会引发异常并终止程序。在这种情况下,无法执行优化。

\n
\n

(强调我的)。如果编译器可以(并且确实)假设我们的程序没有 UB,为什么不能执行此优化?

\n …

c optimization integer-overflow compiler-optimization undefined-behavior

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

C中的浮点运算是关联的吗?

添加在数学上保持关联属性:

(a + b) + c = a + (b + c)
Run Code Online (Sandbox Code Playgroud)

在一般情况下,此属性不适用于浮点数,因为它们表示有限精度的值.

作为优化的一部分,是否允许编译器在从C程序生成机器代码时进行上述替换?它在C标准中的确切位置在哪里?

c math floating-point compiler-optimization

22
推荐指数
2
解决办法
3712
查看次数

快速平方根优化?

如果您查看这个非常好的页面:

http://www.codeproject.com/Articles/69941/Best-Square-Root-Method-Algorithm-Function-Precisi

你会看到这个程序:

#define SQRT_MAGIC_F 0x5f3759df 
 float  sqrt2(const float x)
{
  const float xhalf = 0.5f*x;

  union // get bits for floating value
  {
    float x;
    int i;
  } u;
  u.x = x;
  u.i = SQRT_MAGIC_F - (u.i >> 1);  // gives initial guess y0
  return x*u.x*(1.5f - xhalf*u.x*u.x);// Newton step, repeating increases accuracy 
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:有没有特别的理由为什么这不实现为:

#define SQRT_MAGIC_F 0x5f3759df 
 float  sqrt2(const float x)
{

  union // get bits for floating value
  {
    float x;
    int i;
  } u;
  u.x = …
Run Code Online (Sandbox Code Playgroud)

c optimization

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