相关疑难解决方法(0)

应用程序如何确定指令集是否可用并在可用时使用它?

有趣的是它在游戏和其他软件中的工作原理。
更准确地说,我正在寻求一个解决方案C++
就像是:

if AMX available -> Use AMX version of the math library
else if AVX-512 available -> Use AVX-512 version of the math library
else if AVX-256 available -> Use AVX-256 version of the math library
etc.  
Run Code Online (Sandbox Code Playgroud)

我的基本想法是在不同的 DLL 中编译库并在运行时交换它们,但这对我来说似乎不是最好的解决方案。

c++ windows assembly instruction-set cpuid

18
推荐指数
2
解决办法
2873
查看次数

为 CLANG 编译器提供循环长度断言

我有一个循环将两个float*数组加载到__m256向量中并处理它们。在这个循环之后,我有代码将平衡值加载到向量中,然后处理它们。所以函数上没有对齐要求。

以下是将数据余额加载到向量中的代码:

size_t constexpr            FLOATS_IN_M128              = sizeof(__m128) / sizeof(float);
size_t constexpr            FLOATS_IN_M256              = FLOATS_IN_M128 * 2;
Run Code Online (Sandbox Code Playgroud)

...

assert(bal < FLOATS_IN_M256);

float ary[FLOATS_IN_M256 * 2];    
auto v256f_q = _mm256_setzero_ps();
_mm256_storeu_ps(ary, v256f_q);
_mm256_storeu_ps(&ary[FLOATS_IN_M256], v256f_q);   
float *dest = ary;
size_t offset{};

while (bal--)
{
    dest[offset] = p_q_n[pos];
    dest[offset + FLOATS_IN_M256] = p_val_n[pos];
    offset++;
    pos++;
}

// the two vectors that will be processed
v256f_q = _mm256_loadu_ps(ary);
v256f_val = _mm256_loadu_ps(&ary[FLOATS_IN_M256]);    
Run Code Online (Sandbox Code Playgroud)

assert(bal < FLOATS_IN_M256);当我使用编译器资源管理器时,设置为“x86-64 clang 16.0.0 -march=x86-64-v3 -O3”,编译器会在该行存在时展开循环。但是,assert()在模式中被忽略 …

c++ simd clang compiler-optimization visual-c++

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

错误:内联无法调用always_inline

我正在尝试在一些文件上实现和编码,其中一些包含 SIMD 调用。我已经在服务器上编译了这段代码,运行与我的机器基本相同的操作系统,但我无法编译它。

\n\n

这是错误:

\n\n
make\ng++ main.cpp -march=native -o main -fopenmp\nIn file included from /usr/lib/gcc/x86_64-linux-gnu/7/include/immintrin.h:53:0,\n                 from tensor.hpp:9,\n                 from main.cpp:4:\n/usr/lib/gcc/x86_64-linux-gnu/7/include/avx512vlintrin.h: In function \xe2\x80\x98_ZN6TensorIdE8add_avx2ERKS0_._omp_fn.5\xe2\x80\x99:\n/usr/lib/gcc/x86_64-linux-gnu/7/include/avx512vlintrin.h:447:1: error: inlining failed in call to always_inline \xe2\x80\x98__m256d _mm256_mask_add_pd(__m256d, __mmask8, __m256d, __m256d)\xe2\x80\x99: target specific option mismatch\n _mm256_mask_add_pd (__m256d __W, __mmask8 __U, __m256d __A,\n ^~~~~~~~~~~~~~~~~~\nIn file included from main.cpp:4:0:\ntensor.hpp:228:33: note: called from here\n         res = _mm256_mask_add_pd(tmp, 0xFF, _mm256_mask_loadu_pd(tmp, 0xFF, &elements[i]), _mm256_mask_loadu_pd(tmp, 0xFF, &a.elements[i]));\n               ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nIn file included from /usr/lib/gcc/x86_64-linux-gnu/7/include/immintrin.h:53:0,\n                 from tensor.hpp:9,\n                 from main.cpp:4:\n/usr/lib/gcc/x86_64-linux-gnu/7/include/avx512vlintrin.h:610:1: error: inlining failed in call to …
Run Code Online (Sandbox Code Playgroud)

c++ gcc makefile simd avx

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

如何使用 gcc 或 clang 模拟 _mm256_loadu_epi32?

英特尔的内在指南列出了内在的_mm256_loadu_epi32

_m256i _mm256_loadu_epi32 (void const* mem_addr);
/*
   Instruction: vmovdqu32 ymm, m256
   CPUID Flags: AVX512VL + AVX512F
   Description
       Load 256-bits (composed of 8 packed 32-bit integers) from memory into dst.
       mem_addr does not need to be aligned on any particular boundary.
   Operation
   a[255:0] := MEM[mem_addr+255:mem_addr]
   dst[MAX:256] := 0
*/
Run Code Online (Sandbox Code Playgroud)

但是 clang 和 gcc 不提供这种内在的。相反,他们avx512vlintrin.h仅提供(在文件中)屏蔽版本

_mm256_mask_loadu_epi32 (__m256i, __mmask8, void const *);
_mm256_maskz_loadu_epi32 (__mmask8, void const *);
Run Code Online (Sandbox Code Playgroud)

归结为相同的指令vmovdqu32。我的问题:我怎样才能模仿_mm256_loadu_epi32

 inline _m256i _mm256_loadu_epi32(void const* mem_addr)
 {
      /* …
Run Code Online (Sandbox Code Playgroud)

c c++ intrinsics avx512

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

gcc 编译器开关 (-mavx -mavx2 -mavx512f) 到底有什么作用?

我在 C/C++ 代码中明确使用了英特尔 SIMD 内在扩展。为了编译代码,我需要在命令行上指定 -mavx、-mavx512 或类似的内容。我对这一切都很满意。

然而,从阅读 gcc 手册页来看,并不清楚这些命令行标志是否也告诉 gcc 编译器尝试使用英特尔 SIMD 指令自动矢量化 C/C++ 代码。有人知道情况是否如此吗?-mavx 标志只是允许您手动将 SIMD 内在函数插入代码中,还是还告诉编译器在编译 C/C++ 代码时使用 SIMD 指令?

gcc simd instruction-set avx avx512

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

指定编译器可以使用的函数的 simd 级别

我编写了一些代码,并使用 gcc 和本机架构选项对其进行了编译。

通常,我可以使用此代码并在没有 AVX2(仅 AVX)的旧计算机上运行它,并且它工作正常。然而,编译器似乎实际上正在发出 AVX2 指令(终于!),而不是我需要自己包含 SIMD 内在函数。

我想修改程序,以便支持两种途径(AVX2 和非 AVX2)。换句话说,我想要以下伪代码。

if (AVX2){
   callAVX2Version();
}else if (AVX){
   callAVXVersion();
}else{
   callSSEVersion();
}

void callAVX2Version(){
#pragma gcc -mavx2
}

void callAVXVersion(){
#pragma gcc -mavx
}
Run Code Online (Sandbox Code Playgroud)

我知道如何执行运行时检测部分,我的问题是是否可以执行功能特定的 SIMD 选择部分。

c gcc simd

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

RDRAND和RDSEED内在函数GCC和英特尔C++

英特尔C++编译器和/或GCC是否支持以下内在函数,例如自2012/2013年以来MSVC的内在函数?

int _rdrand16_step(uint16_t*);
int _rdrand32_step(uint32_t*);
int _rdrand64_step(uint64_t*);
int _rdseed16_step(uint16_t*);
int _rdseed32_step(uint32_t*);
int _rdseed64_step(uint64_t*);
Run Code Online (Sandbox Code Playgroud)

如果支持这些内在函数,那么它们支持哪个版本(请使用编译时常量)?

c++ gcc icc intrinsics rdrand

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

调用always_inline'_mm256_add_epi32'时内联失败:目标特定选项不匹配

我正在运行带有 SIMD 指令的 C 代码来测试我的环境。我在 Codeblocks 和 Windows 10 中运行它

#include <immintrin.h>
#include <stdio.h>

#define ARRAY_LENGTH 8

int main(int argc, char* argv[]) {

    __m256i first = _mm256_set_epi32(10, 20, 30, 40, 50, 60, 70, 80);
    __m256i second = _mm256_set_epi32(5, 5, 5, 5, 5, 5, 5, 5);
    __m256i result = _mm256_add_epi32(first, second);

    int* values = (int*) &result;

    for (
        unsigned short i = 0;
        i < ARRAY_LENGTH;
        i += 1
    ) {
        printf("%d ", values[i]);
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这段代码抛出一个错误,我无法修复它。

error: inlining …
Run Code Online (Sandbox Code Playgroud)

c gcc simd codeblocks

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

SIMD 性能缓慢 - 无内联

考虑以下计算 i32 数组总和的示例:

示例1:简单的for循环

pub fn vec_sum_for_loop_i32(src: &[i32]) -> i32 {
    let mut sum = 0;
    for c in src {
        sum += *c;
    }

    sum
}
Run Code Online (Sandbox Code Playgroud)

示例 2:显式 SIMD 求和:

use std::arch::x86_64::*;
// #[inline]
pub fn vec_sum_simd_direct_loop(src: &[i32]) -> i32 {
    #[cfg(debug_assertions)]
    assert!(src.as_ptr() as u64 % 64 == 0);
    #[cfg(debug_assertions)]
    assert!(src.len() % (std::mem::size_of::<__m256i>() / std::mem::size_of::<i32>()) == 0);

    let p_src = src.as_ptr();
    let batch_size = std::mem::size_of::<__m256i>() / std::mem::size_of::<i32>();

    #[cfg(debug_assertions)]
    assert!(src.len() % batch_size == 0);

    let result: i32;
    unsafe {
        let …
Run Code Online (Sandbox Code Playgroud)

sse simd rust avx2

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

运行基本的Avx512代码时获取非法指令

我正在尝试学习AVX指令,并且在运行我收到的基本代码时

非法指令(核心已转储)

该代码在下面提到,我正在使用它进行编译

g ++ -mavx512f 1.cpp

问题到底是什么?如何解决?谢谢!

#include <immintrin.h>
#include<iostream>
using namespace std;

void add(const float a[], const float b[], float res[], int n)
{
    int i = 0;

    for(; i < (n&(~0x31)) ; i+=32 )
    {
        __m512 x = _mm512_loadu_ps( &a[i] );
        __m512 y = _mm512_loadu_ps( &b[i] );

        __m512 z = _mm512_add_ps(x,y);
        _mm512_stream_ps(&res[i],z);
    }

    for(; i<n; i++) res[i] = a[i] + b[i];
}

int main()
{
    int n = 100000;
    float a[n], b[n], res[n];
    for(int i = 0;i …
Run Code Online (Sandbox Code Playgroud)

c c++ avx avx2 avx512

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

为什么内联汇编不能是 constexpr?

C++ 不允许 constexpr 内联汇编有充分的理由吗?为什么 C++20 中允许未计算的内联汇编表达式?

c++ assembly inline-assembly constexpr c++20

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