标签: auto-vectorization

了解gcc 4.9.2自动矢量化输出

我正在尝试学习gcc自动矢量化模块.从这里阅读文档后.

这是我尝试过的(debian jessie amd64):

$ cat ex1.c
int a[256], b[256], c[256];
foo () {
  int i;

  for (i=0; i<256; i++){
    a[i] = b[i] + c[i];
  }
}
Run Code Online (Sandbox Code Playgroud)

然后,我只是运行:

$ gcc  -x c -Ofast -msse2 -c   -ftree-vectorize -fopt-info-vec-missed ex1.c
ex1.c:5:3: note: misalign = 0 bytes of ref b[i_11]
ex1.c:5:3: note: misalign = 0 bytes of ref c[i_11]
ex1.c:5:3: note: misalign = 0 bytes of ref a[i_11]
ex1.c:5:3: note: virtual phi. skip.
ex1.c:5:3: note: num. args = 4 (not unary/binary/ternary …
Run Code Online (Sandbox Code Playgroud)

c gcc auto-vectorization

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

了解SSE指令的矢量化

我试着理解SSE指令的矢量化是如何工作的.

这里是一个实现矢量化的代码片段:

#include <stdlib.h>
#include <stdio.h>

#define SIZE 10000

void test1(double * restrict a, double * restrict b)
{
  int i;

  double *x = __builtin_assume_aligned(a, 16);
  double *y = __builtin_assume_aligned(b, 16);

  for (i = 0; i < SIZE; i++)
  {
    x[i] += y[i];
  }
}
Run Code Online (Sandbox Code Playgroud)

和我的编译命令:

gcc -std=c99 -c example1.c -O3 -S -o example1.s
Run Code Online (Sandbox Code Playgroud)

这里是汇编程序代码的输出:

 .file "example1.c"
  .text
  .p2align 4,,15
  .globl  test1
  .type test1, @function
test1:
.LFB7:
  .cfi_startproc
  xorl  %eax, %eax
  .p2align 4,,10
  .p2align 3
.L3:
  movapd  (%rdi,%rax), %xmm0
  addpd …
Run Code Online (Sandbox Code Playgroud)

c x86 assembly vectorization auto-vectorization

4
推荐指数
1
解决办法
239
查看次数

对C99可变长度数组(VLA)使用限制限定符

我正在探索如何基于函数签名在C99中简单循环的不同实现自动矢量化。

这是我的代码:

/* #define PRAGMA_SIMD _Pragma("simd") */
#define PRAGMA_SIMD

#ifdef __INTEL_COMPILER
#define ASSUME_ALIGNED(a) __assume_aligned(a,64)
#else
#define ASSUME_ALIGNED(a)
#endif

#ifndef ARRAY_RESTRICT
#define ARRAY_RESTRICT
#endif

void foo1(double * restrict a, const double * restrict b, const double * restrict c) 
{ 
    ASSUME_ALIGNED(a);
    ASSUME_ALIGNED(b);
    ASSUME_ALIGNED(c);
    PRAGMA_SIMD
    for (int i = 0; i < 2048; ++i) {
        if (c[i] > 0) {
            a[i] = b[i];
        } else {
            a[i] = 0.0;
        } 
    }
}

void foo2(double * restrict a, const double * restrict b, …
Run Code Online (Sandbox Code Playgroud)

simd c99 variable-length-array restrict-qualifier auto-vectorization

4
推荐指数
1
解决办法
747
查看次数

SSE是多余还是气馁?

在这里和互联网上,我可以找到很多关于现代编译器在许多实际情况下击败SSE的帖子,我刚刚在一些代码中遇到过我在2006年为基于整数的图像处理编写的一些SSE代码并将代码强制降低标准C分支,运行速度更快.

在具有多核和高级流水线等的现代处理器上,较旧的SSE代码是否表现不佳gcc -O2

optimization sse simd auto-vectorization

4
推荐指数
2
解决办法
1638
查看次数

如何使用GCC获得更好的矢量化?

请考虑执行相同计算的以下三个功能:

#include <x86intrin.h>

void testfunc_loop(double a, double b, double* dst)
{
    double f[] = {a,b,-a,-b};

    for(int n = 0; n < 4; ++n)
    {
        dst[n] = 0.1 + f[n]*(1.0 + 0.5*f[n]);
    }
}

void testfunc_flat(double a, double b, double* dst)
{
    dst[0] = 0.1 + ( a)*(1.0 + 0.5*( a));
    dst[1] = 0.1 + ( b)*(1.0 + 0.5*( b));
    dst[2] = 0.1 + (-a)*(1.0 + 0.5*(-a));
    dst[3] = 0.1 + (-b)*(1.0 + 0.5*(-b));
}

void testfunc_avx(double a, double b, double* …
Run Code Online (Sandbox Code Playgroud)

gcc sse clang avx auto-vectorization

4
推荐指数
1
解决办法
559
查看次数

为什么内联函数中的循环无法正确自动向量化?

我试图将一些简单的计算向量化,以加快SIMD架构的速度.但是,我还想将它们作为内联函数,因为函数调用和非向量化代码也需要计算时间.但是,我不能总是同时实现它们.实际上,我的大多数内联函数都无法自动向量化.这是一个简单的测试代码:

inline void add1(double *v, int Length) {
    for(int i=0; i < Length; i++) v[i] += 1;
}

void call_add1(double v[], int L) {
    add1(v, L);
}

int main(){return 0;}
Run Code Online (Sandbox Code Playgroud)

在Mac OS X 10.12.3上,编译它:

clang++ -O3 -Rpass=loop-vectorize -Rpass-analysis=loop-vectorize -std=c++11 -ffast-math test.cpp

test.cpp:2:5: remark: vectorized loop (vectorization width: 2, interleaved count: 2) [-Rpass=loop-vectorize]
    for(int i=0; i < Length; i++) v[i] += 1;
    ^
Run Code Online (Sandbox Code Playgroud)

但是,非常相似的东西(只在call_add1中移动参数)不起作用:

inline void add1(double *v, int Length) {
    for(int i=0; i < Length; i++) v[i] += 1;
} …
Run Code Online (Sandbox Code Playgroud)

c++ inline simd clang++ auto-vectorization

4
推荐指数
1
解决办法
500
查看次数

使用 Rust 自动矢量化

我是 rust/SIMD 新手,我有以下代码片段作为我的程序的瓶颈,我想知道我是否可以利用它的自动向量化功能

fn is_subset(a: Vec<i64>, b: Vec<i64>) -> bool {
    for i in 0..a.len() {
        if (a[i] & !b[i]) != 0 {
            return false;
        }
    }
    true
}
Run Code Online (Sandbox Code Playgroud)

我还有另一种编写方法(使用迭代器,因此可以预先知道行程计数),这会创建自动向量化吗?

fn is_subset(a: Vec<i64>, b: Vec<i64>) -> bool {
    return a.iter().zip(b.iter()).all(|(x, y)| x & y == *x)
}

Run Code Online (Sandbox Code Playgroud)

simd rust auto-vectorization

4
推荐指数
1
解决办法
3381
查看次数

为什么不能在 std::span 上对这个循环进行 clang 矢量化,将结果写入 std::array ?

为什么 clang 17.0.1 不会矢量化以下函数中的循环:

void adapt(std::span<const F, N + 1> signal)
{
    F true_val = signal.back();
    F y = dot_prod<F, N>(&signal[0], w.begin());
    F e = true_val - y;
    F dot = dot_prod<F, N>(&signal[0], &signal[0]);
    F nu = mu / (eps + dot);
    for (size_t i = 0; i < N; i++)
    {
        w[i] += nu * e * signal[i];
    }
}
Run Code Online (Sandbox Code Playgroud)

不存在浮点关联性的附带依赖性或问题,并且 GCC 13.2 对其进行矢量化没有任何问题。

这是编译器资源管理器上完整代码的链接。

其背景是我正在尝试优化我的代码以使用矢量化点积。std::inner_product由于浮点关联性问题,通常会发出标量实现,除非您使用-ffast-math. 但是,我只想-ffast-math应用于单个函数,并且我一直在寻找一种可移植的方法来为 clang 和 GCC 执行此操作。在查看输出时,我注意到 clang 不会矢量化另一个循环。 …

c++ simd vectorization clang auto-vectorization

4
推荐指数
1
解决办法
175
查看次数

内存对齐 QVector().data()

我正在使用 Qt5 编写一个程序,我需要分配一个QVector <float>使其data()指针 32 字节对齐的指针。

无论如何,我可以在不修改 Qt 库本身的情况下做到这一点吗?

我的代码看起来像这样:

QVector <float> vec;
vec.resize(n);
float *wricker_ptr = wricker.data(); // this should be 32-byte aligned
for (int i=0; i<n; i++)
{
    wricker_ptr[i] = /* some computed value */;
}
Run Code Online (Sandbox Code Playgroud)

我正在使用英特尔的 C++ 编译器。

qt vectorization memory-alignment qt5 auto-vectorization

3
推荐指数
1
解决办法
455
查看次数

为什么 Tigerlake 的 gcc 自动矢量化使用 ymm 而不是 zmm 寄存器

我想探索 gcc (10.3) 的自动矢量化。我有以下简短的程序(请参阅https://godbolt.org/z/5v9a53aj6),它计算向量所有元素的总和:

#include <stdio.h>
#define LEN 1024

// -ffast-math -march=tigerlake -O3 -fno-unroll-loops
  
int
main()
{
  float v[LEN] __attribute__ ((aligned(64)));
  float s = 0;
  for (unsigned int i = 0; i < LEN; i++) s += v[i];
  printf("%g\n", s);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我用选项编译-ffast-math -march=tigerlake -O3 -fno-unroll-loops。由于 Tigerlake 处理器具有 avx512,我希望 gcc 自动向量化使用 zmm 寄存器,但它实际上在最内层循环中使用 ymm 寄存器(avx/avx2):

vaddps  ymm0, ymm0, YMMWORD PTR [rax]
Run Code Online (Sandbox Code Playgroud)

如果我替换-march=tigerlake-mavx512f,则使用 zmm 寄存器:

vaddps  zmm0, zmm0, ZMMWORD PTR [rax]
Run Code Online (Sandbox Code Playgroud)

如果我只是指定,为什么不使用 …

c gcc avx auto-vectorization avx512

3
推荐指数
1
解决办法
531
查看次数