【问题标题】:SIMD (SSE) instruction for division in GCCGCC 中用于除法的 SIMD (SSE) 指令
【发布时间】:2010-09-30 21:04:49
【问题描述】:

如果可能,我想使用 SSE 指令优化以下 sn-p:

/*
 * the data structure
 */
typedef struct v3d v3d;
struct v3d {
    double x;
    double y;
    double z;
} tmp = { 1.0, 2.0, 3.0 };

/*
 * the part that should be "optimized"
 */
tmp.x /= 4.0;
tmp.y /= 4.0;
tmp.z /= 4.0;

这可能吗?

【问题讨论】:

  • 为什么不能乘以 0.25?

标签: c optimization gcc sse simd


【解决方案1】:

我在windows下用过SIMD扩展,在linux下还没用过。话虽如此,您应该能够利用DIVPS SSE 操作,它将一个 4 浮点向量除以另一个 4 浮点向量。但是您使用的是双打,所以您需要 SSE2 版本DIVPD。我差点忘了,请确保使用-msse2 开关构建。

我找到了一个页面,其中详细介绍了一些 SSE GCC 内置函数。它看起来有点旧,但应该是一个好的开始。

http://ds9a.nl/gcc-simd/

【讨论】:

【解决方案2】:

tmp.x *= 0.25;够了吗?

请注意,对于 SSE 说明(如果您想使用它们),重要的是:

1) 所有的内存访问都是 16 个字节

2) 操作循环执行

3) 不执行 int float 或 float 双重转换

4) 尽可能避免分裂

【讨论】:

  • 为什么需要循环?它有回报吗?
  • 无论如何,如果您需要帮助,您将不得不从您的代码中发布更多内容,而不仅仅是一条线。
  • 有时避免除法是不正确的。例如,如果数字是 5 而不是 4,则乘以 0.2 而不是除以 5.0 是不正确的(它会产生明显错误的结果),因为没有像 0.2 这样的浮点数(最接近 0.2 的浮点数稍微更少,即 0.19999999999...)。
  • @R 你是对的。但考虑到guest 给出的大量细节,它可能是一个可行的选择。
  • R:在任何情况下,除法的答案与乘以倒数的结果不同吗?
【解决方案3】:

您要查找的内在函数是 _mm_div_pd。这是一个有效的示例,足以引导您朝着正确的方向前进:

#include <stdio.h>

#include <emmintrin.h>

typedef struct
{
    double x;
    double y;
    double z;
} v3d;

typedef union __attribute__ ((aligned(16)))
{
    v3d a;
    __m128d v[2];
} u3d;

int main(void)
{
    const __m128d vd = _mm_set1_pd(4.0);
    u3d u = { { 1.0, 2.0, 3.0 } };

    printf("v (before) = { %g %g %g }\n", u.a.x, u.a.y, u.a.z);

    u.v[0] = _mm_div_pd(u.v[0], vd);
    u.v[1] = _mm_div_pd(u.v[1], vd);

    printf("v (after) = { %g %g %g }\n", u.a.x, u.a.y, u.a.z);

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-10
    • 2020-07-24
    • 2014-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 2019-06-18
    相关资源
    最近更新 更多