标签: sse

提高处理速度的矢量类库

我正在研究并行处理算法以提高处理速度。\n我想测试Agner Fog\ 的矢量类库 VCL

\n\n

我想知道如何选择不同的向量类,例如Vec16c(SSE2 指令集)和Vec32c(AVX 指令集)。

\n\n

我使用的是 Intel\xc2\xae Atom\xe2\x84\xa2 x5-Z8350 处理器,根据规格,它支持 SSE4.2 指令集。

\n\n

如何在硬件支持方面有效选择向量类?\n对于我的处理器,我可以使用 AVX 指令集推荐的 Vec32c 吗?

\n

c++ sse simd avx vector-class-library

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

使用 SSE / AVX Intrinisics 时架构的影响

我想知道编译器如何处理内部函数。

如果使用 SSE2 Intrinsics (Using #include <emmintrin.h>) 并使用-mavx标志进行编译。编译器会生成什么?它会生成 AVX 或 SSE 代码吗?

如果使用 AVX2 Intrinsics (Using #include <immintrin.h>) 并使用-msse2标志进行编译。编译器会生成什么?它会生成 SSE Only 或 AVX 代码吗?

编译器如何处理内部函数?
如果使用 Intrinsics,它是否可以帮助编译器理解循环中的依赖关系以实现更好的矢量化?

例如,这里发生了什么 - https://godbolt.org/z/Y4J5OA(或https://godbolt.org/z/LZOJ2K)?
查看全部 3 个窗格。

上下文

我正在尝试构建具有不同 CPU 功能(SSE4 和 AVX2)的相同功能的各种版本。
我正在使用 SSE Intrinsics 编写相同的版本,并且使用 AVX Intrinsics 编写一次。
假设他们的名字MyFunSSE()是 和MyFunAVX()。两者都在同一个文件中。

如何让编译器(相同的方法适用于 MSVC、GCC 和 ICC)仅使用各自的函数来构建它们?

gcc sse icc intrinsics avx

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

使用 SIMD 内在函数加载或洗牌一对浮点数以实现双精度?

我编写了一些用于处理单精度浮点计算 SIMD 内在函数的优化。

有时,双精度指令比任何单精度指令pd更容易满足我的要求。ps

示例1:

我有指针float prt * ,它指向浮点数块: f0 f1 f2 f3 等。

我想用 [ f0, f1, f0, f1, f0, f1, f0, f1 ] 加载 __m256 值。我没有找到__m256数据类型的 64 位广播。我可以_mm256_broadcast_sd在花车上使用吗?

float* ptr = ...; // pointer to some memory chunk aligned to 4 bytes
__m256 vat = _mm256_castpd_ps( _mm256_broadcast_sd( ( double* )ptr ) );
Run Code Online (Sandbox Code Playgroud)

示例2:

我有 __m256 值 [f0, f1, f2, f3, f4, f5, f6, f7]。我可以使用像 _mm256_srl_epi32 这样的移位指令,它以 __m256i 值作为参数来使用我的 __m256 值进行操作吗? …

c sse simd intrinsics avx

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

AVX 将 __m256i 打包的 32 位整数除以二(无 AVX2)

__m256i我正在寻找使用 AVX 将压缩的 32 位整数除以二(也称为右移一位)的最快方法。我无法访问 AVX2。据我所知,我的选择是:

  1. 下拉至SSE2
  2. 类似于有符号 32 位元素的 AVX __m256i 整数除法

如果我需要使用 SSE2,我会欣赏最好的 SSE2 实现。如果是 2),我想知道要使用的内在函数,以及是否有更优化的实现来专门除以 2。谢谢!

c++ sse simd avx sse2

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

有没有更好的方法来检测 16 字节标志数组中设置的位?

    ALIGNTO(16) uint8_t noise_frame_flags[16] = { 0 };

    // Code detects noise and sets noise_frame_flags omitted

    __m128i xmm0            = _mm_load_si128((__m128i*)noise_frame_flags);
    bool    isNoiseToCancel = _mm_extract_epi64(xmm0, 0) | _mm_extract_epi64(xmm0, 1);

    if (isNoiseToCancel)
        cancelNoises(audiobuffer, nAudioChannels, audio_samples, noise_frame_flags);
Run Code Online (Sandbox Code Playgroud)

这是我在 Linux 上的 AV Capture 工具的代码片段。这里的noise_frame_flags是16通道音频的标志数组。对于每个通道,相应的字节可以是 0 或 1。1 表示该通道有一些噪声需要消除。例如,如果noise_frame_flags[0] == 1,则意味着设置了第一个通道噪声标志(通过省略的代码)。

即使设置了一个“标志”,我也需要调用cancelNoises. 这段代码在这方面似乎工作得很好。正如您所看到的,我曾经_mm_load_si128加载正确对齐的整个标志数组,然后加载两个_mm_extract_epi64来提取“标志”。我的问题是有更好的方法来做到这一点(也许使用流行计数)?

注意:ALIGNTO(16)是一个宏扩展以纠正 GCC 等效项,但外观更好。

c++ sse x86-64 simd micro-optimization

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

int32_t 和 int16_t 之间的 sse4 压缩和(符号扩展至 int32_t)

我有以下代码片段(可以在此处找到要点),其中我尝试对 4 个 int32_t 负值和 4 个 int16_t 值(将符号扩展为 int32_t)之间进行求和。

    extern  exit

    global _start

    section .data

a:     dd -76, -84, -84, -132
b:     dw 406, 406, 406, 406
    
    section .text
_start:
    movdqa xmm0, [a]
    pmovsxwd xmm2, [b]
    paddq xmm0, xmm2
    ;Expected: 330, 322, 322, 274
    ;Results:  330, 323, 322, 275
    call exit
Run Code Online (Sandbox Code Playgroud)

然而,当通过我的调试器时,我无法理解为什么输出结果与预期结果不同。任何想法 ?

linux sse x86-64 intel

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

x86 内在:2 个复数浮点向量的乘法

我的输入是 2 个复数浮点向量。两个向量交错:

VecAReal = Are0, Are1, Are2,...Are[N-1]
VecAImag = Aim0, Aim1, Aim2,...Aim[N-1]

VecBReal = Bre0, Bre1, Bre2,...Bre[N-1]
VecBImag = Bim0, Bim1, Bim2,...Bim[N-1]
Run Code Online (Sandbox Code Playgroud)

我必须运行标量乘法:

VecCReal = Cre0, Cre1, Cre2,...Cre[N-1]
VecCImag = Cim0, Cim1, Cim2,...Cim[N-1]


Cre[i] = Are[i]*Bre[i] - Aim[i]-Bim[i]
Cim[i] = Are[i]*Bim[i] + Aim[i]+Bre[i]
Run Code Online (Sandbox Code Playgroud)

在每次迭代中,我必须_mm_load_ps在 4 个不同的指针上运行。

在 sum、add 之后,在每次迭代中我必须_mm_store_ps在 2 个不同的指针上运行。

由于大量加载/存储,它看起来效率很低。你能建议一个更好的方法吗?

c x86 sse intrinsics complex-numbers

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

首先 movss,然后用零 unpcklps,不改变高零。为什么?

我是 x86 的新手,没有任何经验,所以这段代码对我来说看起来有点过时了。这样做有什么目的吗?

说明是:

rcx+000003F8 = 32 位浮点数

xmm0 = 0(全部 128 位)

movss xmm4,[rcx+000003F8]
unpcklps xmm4,xmm0
Run Code Online (Sandbox Code Playgroud)

“unpcklps xmm4,xmm0”会不会过时,因为它不会改变 xmm4 中的任何内容?

x86 assembly sse x86-64

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

SIMD内在和内存总线大小 - CPU如何读取单个内存中的所有128/256位读取?

你好论坛 - 我有一些关于SIMD内在的类似/相关问题我在网上搜索了包括stackoverflow但没有找到好的答案所以请求你的帮助.

基本上我试图理解64位CPU如何在一次读取中获取所有128位,以及这种操作的要求是什么.

  1. CPU会在单个内存操作中从内存中获取所有128位还是会进行两次64位读取?
  2. CPU制造商是否需要一定大小的内存总线,例如,对于64位CPU,英特尔需要128位总线来进行SSE内存绑定操作吗?
  3. 这些操作是否依赖于内存总线大小,通道数和内存模块数量?

sse x86-64 simd cpu-architecture memory-bandwidth

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

用另一个替换一个字节

我发现在为这个看似简单的问题创建代码时遇到了困难.

给定一个打包的8位整数,如果存在则用另一个字节替换另一个字节

举例来说,我想替换0x060x01,所以我可以做以下res的输入找到0x06:

// Bytes to be manipulated
res = _mm_set_epi8(0x00, 0x03, 0x02, 0x06, 0x0F, 0x02, 0x02, 0x06, 0x0A, 0x03, 0x02, 0x06, 0x00, 0x00, 0x02, 0x06);

// Target value and substitution
val = _mm_set1_epi8(0x06);
sub = _mm_set1_epi8(0x01);

// Find the target
sse = _mm_cmpeq_epi8(res, val);

// Isolate target
sse = _mm_and_si128(res, sse);

// Isolate remaining bytes
adj = _mm_andnot_si128(sse, res);
Run Code Online (Sandbox Code Playgroud)

现在我不知道如何继续or这两个部分,我需要删除目标并用替换的字节替换它.

我在这里缺少什么SIMD指令?

和其他问题一样,我只限于AVX,我没有更好的处理器.

sse simd avx

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