相关疑难解决方法(0)

AVX2中的8位移位操作,零移位

有没有办法_mm_slli_si128在AVX2中重建指令以将__mm256i寄存器移位x个字节?

_mm256_slli_si256似乎只是执行两个_mm_slli_si128上的[127:0]和A [255:128].

左移应该__m256i是这样的:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, ..., 32] -> [2, 3, 4, 5, 6, 7, 8, 9, ..., 0]
Run Code Online (Sandbox Code Playgroud)

我在线程中看到可以创建一个_mm256_permutevar8x32_ps32位的移位.但我需要一个更通用的解决方案来换班x字节.有人已经解决了这个问题吗?

c sse simd avx avx2

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

使用未对齐缓冲区进行矢量化:使用VMASKMOVPS:根据未对齐计数生成掩码?或者根本不使用那个insn

gcc 5.3 with -O3 -mavx -mtune=haswellfor x86-64使得代码处理可能错位的代码变得非常笨重,例如:

// convenient simple example of compiler input
// I'm not actually interested in this for any real program
void floatmul(float *a) {
  for (int i=0; i<1024 ; i++)
    a[i] *= 2;
}
Run Code Online (Sandbox Code Playgroud)

clang使用未对齐的加载/存储指令,但是gcc执行标量intro/outro和对齐的向量循环:它剥离了第一个最多7个未对齐的迭代,将其完全展开为一个序列

    vmovss  xmm0, DWORD PTR [rdi]
    vaddss  xmm0, xmm0, xmm0      ; multiply by two
    vmovss  DWORD PTR [rdi], xmm0
    cmp     eax, 1
    je      .L13
    vmovss  xmm0, DWORD PTR [rdi+4]
    vaddss  xmm0, xmm0, xmm0
    vmovss …
Run Code Online (Sandbox Code Playgroud)

x86 assembly gcc sse avx

10
推荐指数
2
解决办法
960
查看次数

如何使用AVX2有效地连接两个向量?(VPALIGNR的交叉版本)

我已经实现了内联函数(_mm256_concat_epi16).它连接两个包含16位值的AVX2向量.它适用于前8个数字.如果我想将它用于向量的其余部分,我应该更改实现.但是在我的主程序中使用单个内联函数会更好.

问题是:有没有比我的更好的解决方案或任何建议使这个内联函数更通用,它适用于16个值而不是我的解决方案适用于8个值?我的解决方案连接2个向量,但只解决了16个可能状态的8个状态.

**编辑*我对这个问题的当前解决方案是使用未对齐的加载函数,它可以从内存中的任何部分读取.但是,当数据在寄存器中准备就绪时,重用它可能会更好.但是,它可能会导致端口5出现瓶颈,导致混乱,置换等.但吞吐量可能已足够(尚未测试).

#include <stdio.h>
#include <x86intrin.h>

inline _mm256_print_epi16(__m256i a, char* name){
    short temp[16], i;
    _mm256_storeu_si256((__m256i *) &temp[0], a);
    for(i=0; i<16; i++)
        printf("%s[%d]=%4d , ",name,i+1,temp[i]);
    printf("\n");
}

inline __m256i _mm256_concat_epi16(__m256i a, __m256i  b, const int indx){
    return _mm256_alignr_epi8(_mm256_permute2x128_si256(a,b,0x21),a,indx*2);
}

int main()
{
    __m256i a = _mm256_setr_epi16(101,102,103,104,105,106,107,108,109,1010,1011,1012,1013,1014,1015,1016);_mm256_print_epi16(a, "a");
    __m256i b = _mm256_setr_epi16(201,202,203,204,205,206,207,208,209,2010,2011,2012,2013,2014,2015,2016);_mm256_print_epi16(b, "b");

    _mm256_print_epi16(_mm256_concat_epi16(a,b,8), "c");//numbers: 0-8
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

出局是:

// icc  -march=native -O3 -D _GNU_SOURCE -o "concat" "concat.c"
[fedora@localhost concatination]$ "./concat"
a[1]= 101 …
Run Code Online (Sandbox Code Playgroud)

c simd intrinsics avx avx2

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

SIMD版本的SHLD/SHRD指令

SHLD/SHRD指令是用于实现多精度移位的汇编指令.

请考虑以下问题:

uint64_t array[4] = {/*something*/};
left_shift(array, 172);
right_shift(array, 172);
Run Code Online (Sandbox Code Playgroud)

什么是实行最有效的方法left_shiftright_shift,经营4个64位无符号整数数组上的转变,就好像它是一个巨大的256位无符号整数两种功能?

最有效的方法是使用SHLD/SHRD指令,还是有更好的(如SIMD版本)现代架构指令?

c assembly x86-64 bit-shift arbitrary-precision

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

将 AVX 256 矢量元素按左/右 1 个位置 - C 内在函数

我试图找到一种更有效的方法来“旋转”或将 avx _m256 向量中的 32 位浮点值向右或向左移动一个位置。

这样:

a7、a6、a5、a4、a3、a2、a1、a0

变成

0、a7、a6、a5、a4、a3、a2、a1

(我不介意在我更换单元格时数据是否丢失。)

我已经看过这个线程:Emulating shifts on 32 bytes with AVX 但我真的不明白发生了什么,它也没有解释 _MM_SHUFFLE(0, 0, 3, 0) 的作用一个输入参数。


我正在尝试优化此代码:

_mm256_store_ps(temp, array[POS(ii, jj)]);
_mm256_store_ps(left, array[POS(ii, jj-1)]);

tmp_array[POS(ii, jj)] = _mm256_set_ps(left[0], temp[7], temp[6], temp[5], temp[4], temp[3], temp[2], temp[1]);
Run Code Online (Sandbox Code Playgroud)

我知道一旦轮班到位,我可以使用插入来替换剩余的单元格。我觉得这会比解压到 float[8] 数组并重建更有效。

-- 我还希望能够左右移动,因为我需要在其他地方执行类似的操作。

任何帮助是极大的赞赏!谢谢!

c hpc sse intrinsics avx

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

如何在AVX2中实现车道交叉逻辑按位移位/旋转(左和右)

根据这个答案,我创建了以下测试程序:

#include <iso646.h>
#include <immintrin.h>

#include <stdio.h>

#define SHIFT_LEFT( N ) \ 
\
    inline __m256i shift_left_##N ( __m256i A  ) { \
\
    if ( N == 0 ) return A; \
    else if ( N <  16 ) return _mm256_alignr_epi8 ( A, _mm256_permute2x128_si256 ( A, A, _MM_SHUFFLE ( 0, 0, 2, 0 ) ), ( uint8_t ) ( 16 - N ) ); \
    else if ( N == 16 ) return _mm256_permute2x128_si256 ( A, A, _MM_SHUFFLE …
Run Code Online (Sandbox Code Playgroud)

c c++ avx2

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

使用向量指令进行复杂的数据重组

我需要按照下面的模式加载并重新排列12个字节到16(或24到32):

ABC DEF GHI JKL
Run Code Online (Sandbox Code Playgroud)

ABBC DEEF GHHI JKKL
Run Code Online (Sandbox Code Playgroud)

您能否建议使用SSE(2)和/或AVX(2)指令实现此目的的有效方法?

这需要重复执行,因此允许预先存储的掩码或常量.

x86 simd vectorization sse2 avx2

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

标签 统计

c ×5

avx ×4

avx2 ×4

simd ×3

sse ×3

assembly ×2

intrinsics ×2

x86 ×2

arbitrary-precision ×1

bit-shift ×1

c++ ×1

gcc ×1

hpc ×1

sse2 ×1

vectorization ×1

x86-64 ×1