标签: auto-vectorization

gcc自动矢量化(未处理的数据参考)

我不明白为什么这样的代码没有用gcc 4.4.6进行矢量化

int MyFunc(const float *pfTab, float *pfResult, int iSize, int iIndex)
{
  for (int i = 0; i < iSize; i++)
     pfResult[i] = pfResult[i] + pfTab[iIndex];
}

 note: not vectorized: unhandled data-ref
Run Code Online (Sandbox Code Playgroud)

但是,如果我写下面的代码

   int MyFunc(const float *pfTab, float *pfResult, int iSize, int iIndex)
{
  float fTab =  pfTab[iIndex];
  for (int i = 0; i < iSize; i++)
     pfResult[i] = pfResult[i] + fTab;
}
Run Code Online (Sandbox Code Playgroud)

gcc成功自动向量化此循环

如果我添加omp指令

   int MyFunc(const float *pfTab, float *pfResult, int iSize, int iIndex)
{
  float fTab = …
Run Code Online (Sandbox Code Playgroud)

gcc openmp auto-vectorization

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

为什么"#pragma omp simd"在gcc编译器下只能在"-O2"中获得很大的性能提升?

检查以下代码:

#include <stdio.h>
#include <omp.h>

#define ARRAY_SIZE  (1024)
float A[ARRAY_SIZE];
float B[ARRAY_SIZE];
float C[ARRAY_SIZE];

int main(void)
{   
    for (int i = 0; i < ARRAY_SIZE; i++)
    {
        A[i] = i * 2.3;
        B[i] = i + 4.6;
    }

    double start = omp_get_wtime();
    for (int loop = 0; loop < 1000000; loop++)
    {
        #pragma omp simd
        for (int i = 0; i < ARRAY_SIZE; i++)
        {
            C[i] = A[i] * B[i];
        }
    }
    double end = omp_get_wtime();
    printf("Work consumed %f seconds\n", …
Run Code Online (Sandbox Code Playgroud)

performance gcc simd openmp auto-vectorization

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

为什么 Rust 编译器不能自动向量化这个 FP 点积实现?

让我们考虑一个简单的简化,例如点积:

pub fn add(a:&[f32], b:&[f32]) -> f32 {
    a.iter().zip(b.iter()).fold(0.0, |c,(x,y)| c+x*y))
}
Run Code Online (Sandbox Code Playgroud)

使用 rustc 1.68 与-C opt-level=3 -C target-feature=+avx2,+fma 我得到

.LBB0_5:
        vmovss  xmm1, dword ptr [rdi + 4*rsi]
        vmulss  xmm1, xmm1, dword ptr [rdx + 4*rsi]
        vmovss  xmm2, dword ptr [rdi + 4*rsi + 4]
        vaddss  xmm0, xmm0, xmm1
        vmulss  xmm1, xmm2, dword ptr [rdx + 4*rsi + 4]
        vaddss  xmm0, xmm0, xmm1
        vmovss  xmm1, dword ptr [rdi + 4*rsi + 8]
        vmulss  xmm1, xmm1, dword ptr [rdx + …
Run Code Online (Sandbox Code Playgroud)

floating-point simd rust auto-vectorization fast-math

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

GCC 自动矢量化

在 gcc 编译器中有没有办法只启用自动矢量化?我确实知道该-ftree-vectorize标志可以启用自动矢量化。但它至少需要-O2优化级别。有没有办法在不使用-O2优化标志的情况下启用自动矢量化?

提前致谢。

gcc compiler-optimization auto-vectorization

2
推荐指数
1
解决办法
1299
查看次数

为什么gcc -O3自动矢量分解?很多额外的指令看起来更糟

这是一个非常简单的阶乘函数。

int factorial(int num) {
    if (num == 0)
        return 1;
    return num*factorial(num-1);
}
Run Code Online (Sandbox Code Playgroud)

GCC在-O2上为此功能进行的组装是合理的。

factorial(int):
        mov     eax, 1
        test    edi, edi
        je      .L1
.L2:
        imul    eax, edi
        sub     edi, 1
        jne     .L2
.L1:
        ret
Run Code Online (Sandbox Code Playgroud)

但是,在-O3或-Ofast上,它决定使事情变得更复杂(几乎100行!):

factorial(int):
        test    edi, edi
        je      .L28
        lea     edx, [rdi-1]
        mov     ecx, edi
        cmp     edx, 6
        jbe     .L8
        mov     DWORD PTR [rsp-12], edi
        movd    xmm5, DWORD PTR [rsp-12]
        mov     edx, edi
        xor     eax, eax
        movdqa  xmm0, XMMWORD PTR .LC0[rip]
        movdqa  xmm4, XMMWORD PTR .LC2[rip]
        shr …
Run Code Online (Sandbox Code Playgroud)

x86 gcc x86-64 compiler-optimization auto-vectorization

2
推荐指数
1
解决办法
185
查看次数

GCC矢量化语用

使用intel编译器,如果用户确认没有使用依赖关系,则仍然可以对循环进行矢量化#pragma ivdep.

我在GCC找到了一个#pragma GCC ivdep,但收到如下错误:

warning: ignoring #pragma GCC ivdep [-Wunknown-pragmas] #pragma GCC ivdep

gcc pragma vectorization icc auto-vectorization

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

这个矢量化代码如何不覆盖内存?

拿这个代码。

#include <stdlib.h>

int main(int argc , char **argv) {
    int *x = malloc(argc*sizeof(int));
    
    for (int i = 0; i < argc; ++i) {
        x[i] = argc;
    }

    int t = 0;
    for (int i = 0; i < argc; ++i) {
        t += x[i];
    }

    free(x);
    return t;
Run Code Online (Sandbox Code Playgroud)

这个循环

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

向量化为

        movdqu  xmmword ptr [rax + 4*rdx], xmm0
        movdqu  xmmword ptr [rax + 4*rdx + 16], …
Run Code Online (Sandbox Code Playgroud)

c compiler-construction simd clang auto-vectorization

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

理解 JIT 对 for 循环的重写

我有以下Java代码(所有数组在我们调用“arrays”之前都已初始化,并且所有数组的大小均为“arraySize”)

int arraySize = 64;

float[] a;
float[] b;
float[] result;

public void arrays() {
    for (int i = 0; i < arraySize; i++) {
        result[i] = ((a[i] * b[i] + b[i] - b[i]) / b[i]) +
                     a[i] + a[i] + a[i] + a[i];
    }
}
Run Code Online (Sandbox Code Playgroud)

JIT 的输出是:

# {method} {0x00000001034751a8} 'arrays' '()V' in 'main/ComplexExpression'
#           [sp+0x30]  (sp of caller)
[Entry Point]
0x000000010c4c55a0: mov 0x8(%rsi),%r10d
0x000000010c4c55a4: movabs $0x800000000,%r11
0x000000010c4c55ae: add %r11,%r10
0x000000010c4c55b1: cmp %r10,%rax
0x000000010c4c55b4: jne 0x000000010c44b780  ;   {runtime_call ic_miss_stub} …
Run Code Online (Sandbox Code Playgroud)

java assembly jit x86-64 auto-vectorization

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

为什么C / RUST中的一个加法计算在结果ASM中有3个双精度浮点加法工具?

简单的C代码,只需添加一个双精度。

void test(double *a, double *b, long n) {
    for (long j = 0; j < n; j++)
    for (long i = 0; i < n; i++) {
        b[i] = b[i] + a[j];
    }
}
Run Code Online (Sandbox Code Playgroud)

在编译器资源管理器中获取ASM结果:https : //godbolt.org/z/tJ-d39

有一addpd和二addsd。两者都是与双精度有关的。

另一个类似的锈代码,获得了更多的双精度添加工具:https//godbolt.org/z/c49Wuh

pub unsafe fn test(a: &mut [f64], b: &mut [f64], n: usize) {
    for j in 0..n {
        for i in 0..n {
            *b.get_unchecked_mut(i) = *b.get_unchecked_mut(i) + *a.get_unchecked_mut(j);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

c assembly simd rust auto-vectorization

-1
推荐指数
2
解决办法
113
查看次数