首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >把复数数组的乘积向量化

把复数数组的乘积向量化
EN

Code Review用户
提问于 2017-01-16 11:39:48
回答 1查看 553关注 0票数 10

我正在尝试编写快速/最优的代码,将复数数组的乘积矢量化。在简单的C中,这将是:

代码语言:javascript
复制
#include <complex.h>
complex float f(complex float x[], int n ) {
  complex float p = 1.0;
  for (int i = 0; i < n; i++)
    p *= x[i];
  return p;
}

然而,gcc不能矢量化这一点,我的目标CPU是AMD FX-8350,它支持AVX。为了加快速度,我试过:

代码语言:javascript
复制
typedef float v4sf __attribute__ ((vector_size (16)));
typedef union {
  v4sf v;
  float e[4];
} float4;
typedef struct {
  float4 x;
  float4 y;
} complex4;
static complex4 complex4_mul(complex4 a, complex4 b) {
  return (complex4){a.x.v*b.x.v -a.y.v*b.y.v, a.y.v*b.x.v + a.x.v*b.y.v};
}
complex4 f4(complex4 x[], int n) {
  v4sf one = {1,1,1,1};
  complex4 p = {one,one};
  for (int i = 0; i < n; i++) p = complex4_mul(p, x[i]);
  return p;
}

对于AVX,这段代码可以改进吗?它是否尽可能快?

EN

回答 1

Code Review用户

发布于 2017-12-21 23:19:14

我想知道编译器是否能够更容易地将其矢量化,而不需要union内的structe成员的潜在类型双关语(这似乎没有被使用)。

这个怎么样?

代码语言:javascript
复制
typedef float v4sf __attribute__ ((vector_size (16)));
typedef struct {
  v4sf x;
  v4sf y;
} complex4;

static inline v4sf complex4_mul_r(v4sf a_r, v4sf a_i, v4sf b_r, v4sf b_i) {
  return a_r*b_r -a_i*b_i;
}
static inline v4sf complex4_mul_i(v4sf a_r, v4sf a_i, v4sf b_r, v4sf b_i) {
  return a_r*b_i + a_i*b_r;
}

complex4 f4(v4sf x_r[], v4sf x_i[], int n) {
  v4sf one = {1,1,1,1};
  v4sf p_r = one;
  v4sf p_i = one;
  v4sf p_r_temp;
  for (int i = 0; i < n; i++)
  {
     p_r_temp = complex4_mul_r(p_r, p_i, x_r[i], x_i[i]);
     p_i = complex4_mul_i(p_r, p_i, x_r[i], x_i[i]);
     p_r = p_r_temp;
  }
  return (complex4){p_r, p_i};
}

看一下https://godbolt.org/上的程序集,它似乎得到了完全的矢量化。我无法让“上帝”共享链接开始工作。

我在考虑是否有可能将实部和虚部放在同一个向量中,并在必要时使用__builtin_shuffle()对它们进行排列。不能完全解决这个问题。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/152759

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档