相关疑难解决方法(0)

AVX2什么是基于面具打包左边最有效的方法?

如果你有一个输入数组和一个输出数组,但是你只想写那些通过某个条件的元素,那么在AVX2中这样做最有效的方法是什么?

我在SSE看到它是这样做的:(来自:https://deplinenoise.files.wordpress.com/2015/03/gdc2015_afredriksson_simd.pdf)

__m128i LeftPack_SSSE3(__m128 mask, __m128 val)
{
 // Move 4 sign bits of mask to 4-bit integer value.
 int mask = _mm_movemask_ps(mask);
 // Select shuffle control data
 __m128i shuf_ctrl = _mm_load_si128(&shufmasks[mask]);
 // Permute to move valid values to front of SIMD register
 __m128i packed = _mm_shuffle_epi8(_mm_castps_si128(val), shuf_ctrl);
 return packed;
}
Run Code Online (Sandbox Code Playgroud)

这对于4宽的SSE来说似乎很好,因此只需要16个入口LUT,但对于8宽的AVX,LUT变得非常大(256个条目,每个32个字节或8k).

我很惊讶AVX似乎没有简化此过程的指令,例如带有打包的蒙版存储.

我想通过稍微改变来计算左边设置的符号位数,你可以生成必要的排列表,然后调用_mm256_permutevar8x32_ps.但这也是我认为的一些指示......

有没有人知道用AVX2做这个的任何技巧?或者什么是最有效的方法?

以下是上述文件中左包装问题的说明:

Left.Packing.Problem

谢谢

c++ sse simd vectorization avx2

26
推荐指数
5
解决办法
6865
查看次数

如何执行_mm256_movemask_epi8(VPMOVMSKB)的反转?

内在的:

int mask = _mm256_movemask_epi8(__m256i s1)
Run Code Online (Sandbox Code Playgroud)

创建一个掩码,其32位对应于每个字节的最高位s1.在使用位操作(BMI2例如)操作掩码之后,我想执行反转_mm256_movemask_epi8,即创建一个__m256i向量,每个字节的最高有效位包含相应的位uint32_t mask.

做这个的最好方式是什么?

编辑:我需要执行逆操作,因为内在函数_mm256_blendv_epi8只接受__m256i类型掩码而不是uint32_t.因此,在结果__m256i掩码中,我可以忽略除每个字节的MSB之外的位.

c x86 simd avx avx2

21
推荐指数
2
解决办法
4378
查看次数

是否有针对intel avx2中的movemask指令的反向指令?

movemask指令采用__m256i并返回int32,其中每个位(取决于输入向量元素类型的前4位,8位或所有32位)是相应向量元素的最高有效位.

我想做反过来:取一个32(其中只有4,8或32个最低有效位有意义),并获得__m256i,其中每个int8,int32或int64大小的块的最高有效位设置为原始位.

基本上,我想从压缩的位掩码转到可被其他AVX2指令(例如maskstore,maskload,mask_gather)用作掩码的位掩码.

我无法快速找到这样做的指令,所以我在这里问.如果没有一条具有该功能的指令,您是否可以想到一个聪明的黑客,只需很少的指令即可实现这一点?

我目前的方法是使用256元素查找表.我想在一个没有其他事情发生的循环中使用这个操作来加速它.注意,我对长多指令序列或实现此操作的小循环不太感兴趣.

x86 icc intrinsics avx avx2

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

为什么在AMD64上对mmap内存的未对齐访问有时会出现段错误?

我有这段代码在AMD64兼容CPU上运行Ubuntu 14.04时会出现段错误:

#include <inttypes.h>
#include <stdlib.h>

#include <sys/mman.h>

int main()
{
  uint32_t sum = 0;
  uint8_t *buffer = mmap(NULL, 1<<18, PROT_READ,
                         MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
  uint16_t *p = (buffer + 1);
  int i;

  for (i=0;i<14;++i) {
    //printf("%d\n", i);
    sum += p[i];
  }

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

如果使用分配内存,则仅此段错误mmap.如果我使用malloc,堆栈上的缓冲区,或全局变量,它不会段错误.

如果我将循环的迭代次数减少到少于14的次数,则不再是段错误.如果我从循环内打印数组索引,它也不再是段错误.

为什么未对齐的内存访问能够访问未对齐地址的CPU上的段错误,为什么只有在这种特定情况下呢?

c gcc mmap x86-64 auto-vectorization

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

是否可以使用SIMD指令进行替换?

我有int的向量,我需要找到替换一些具有特定值的元素.两者都是一样的.
例如:为所有元素替换4到8.

我在c ++中尝试循环内存访问.但它对我来说仍然很慢.

更新:
我正在使用OpenCV Mat对象x86:

for (int i = 0; i < labels.rows; ++i) {
    for (int j = 0; j < labels.cols; ++j) {
        int& label = labels.at<int>(i, j);
        if (label == oldValue) {
            label = newValue;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Mat.at() 函数只是在释放模式下通过指针返回值

template<typename _Tp> inline
_Tp& Mat::at(int i0, int i1)
{
    CV_DbgAssert(dims <= 2);
    CV_DbgAssert(data);
    CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
    CV_DbgAssert((unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()));
    CV_DbgAssert(CV_ELEM_SIZE1(traits::Depth<_Tp>::value) …
Run Code Online (Sandbox Code Playgroud)

c++ algorithm replace simd

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

标签 统计

avx2 ×3

simd ×3

avx ×2

c ×2

c++ ×2

x86 ×2

algorithm ×1

auto-vectorization ×1

gcc ×1

icc ×1

intrinsics ×1

mmap ×1

replace ×1

sse ×1

vectorization ×1

x86-64 ×1