相关疑难解决方法(0)

英特尔x86汇编优化技术中的示例问题

我正在学习汇编程序很长一段时间,我正在尝试重写一些简单的过程\函数来查看性能优势(如果有的话).我的主要开发工具是Delphi 2007,第一个例子将使用该语言,但它们也可以很容易地翻译成其他语言.

问题表明:

我们给出了一个无符号字节值,其中八位中的每一位代表一行屏幕中的一个像素.每个单个像素可以是实心(1)或透明(0).换句话说,我们在一个字节值中包含8个像素.我想将这些像素解压缩成一个8字节的数组,就像最年轻的像素(位)将落在数组的最低索引之下一样,依此类推.这是一个例子:

One byte value -----------> eight byte array

10011011 -----------------> [1][1][0][1][1][0][0][1]

Array index number ------->  0  1  2  3  4  5  6  7
Run Code Online (Sandbox Code Playgroud)

下面我介绍解决问题的五种方法.接下来,我将展示他们的时间比较以及我如何衡量这些时间.

我的问题包括两部分:

1.

我问您详细的有关方法的答案DecodePixels4a和DecodePixels4b.为什么方法4b有点慢4a?

例如,如果我的代码没有正确对齐,它会慢一些,那么告诉我给定方法中哪些指令可以更好地对齐,以及如何做到这一点不破坏方法.

我想看看这个理论背后的真实例子.请记住,我正在学习汇编,我想从你的答案中获得知识,这使我将来能够编写更好的优化代码.

2.

你能写更快的常规DecodePixels4a吗?如果是,请提供并描述您已采取的优化步骤.通过更快的例程,我的意思是在测试环境中在最短的时间段内运行的例程,在此处提供的所有例程中.

允许使用所有Intel系列处理器以及与之兼容的处理器.

您将在下面找到我编写的例程:

procedure DecodePixels1(EncPixels: Byte; var DecPixels: TDecodedPixels);
var
  i3: Integer;
begin
  DecPixels[0] := EncPixels and $01;
  for i3 := 1 to 7 do
  begin
    EncPixels := EncPixels shr 1;
    DecPixels[i3] := …
Run Code Online (Sandbox Code Playgroud)

delphi optimization x86 assembly basm

21
推荐指数
3
解决办法
3835
查看次数

是否有针对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
查看次数

将32位解压缩为32字节SIMD向量的最快方法

将32位存储在uint32_t内存中,将每个位解压缩到AVX寄存器的单独字节元素的最快方法是什么?这些位可以位于各自字节内的任何位置.

编辑:澄清,我的意思是位0进入字节0,位1到字节1.显然,字节内的所有其他位都为零.我现在最好的是2 PSHUFB并且每个位置都有一个掩码寄存器.

如果uint32_t是位图,则相应的向量元素应为0或非0.(即我们可以得到一个矢量掩码,其中vpcmpeqb一个矢量为全零的矢量).

https://software.intel.com/en-us/forums/topic/283382

x86 simd avx avx2

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

_mm_movemask_epi8 的内在逆

首先我将描述该任务:

我需要:

  1. 比较两个__m128i。
  2. 以某种方式对结果进行按位与某个uint16_t值(可能使用_mm_movemask_epi8先然后只是&)。
  3. 根据blend结果​​计算初始值。

所以问题是,正如您可能已经猜到的那样,混合接受__m128i作为掩模,而我将拥有uint16_t. 因此,我要么需要某种反向指令,_mm_movemask_epi8要么完全做其他事情。

有些观点——我可能无法将该uint16_t值更改为其他类型,这很复杂;我在 SSE4.2 上这样做,所以没有 AVX;这里有一个类似的问题How to Perform the inverse of _mm256_movemask_epi8 (VPMOVMSKB)? 但这是关于 avx 的,我对此非常缺乏经验,所以我无法采用该解决方案。

PS:我可能也需要为手臂做这件事,希望得到任何建议。

c x86 sse simd sse4

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

如何在没有AVX2的情况下使用字节中的位来设置ymm寄存器中的dword?(反向vmovmskps)

我想要实现的是基于一个字节中的每个位,设置为ymm寄存器(或内存位置)中每个dword中的所有位

例如

al = 0110 0001

ymm0 = 0x00000000 FFFFFFFF FFFFFFFF 00000000 00000000 00000000 00000000 FFFFFFFF
Run Code Online (Sandbox Code Playgroud)

即vmovmskps eax, ymm0/ 的倒数_mm256_movemask_ps,将位图转换为矢量蒙版.

我想有一些sse/avx指令可以相对简单地做到这一点,但我还是无法解决这个问题.优选沙桥兼容,因此没有avx2.

assembly sse x86-64 avx

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

将 16 位掩码转换为 16 字节掩码

有没有办法转换以下代码:

int mask16 = 0b1010101010101010; // int or short, signed or unsigned, it does not matter
Run Code Online (Sandbox Code Playgroud)

到

__uint128_t mask128 = ((__uint128_t)0x0100010001000100 << 64) | 0x0100010001000100;
Run Code Online (Sandbox Code Playgroud)

所以要特别清楚,比如:

int mask16 = 0b1010101010101010; 
__uint128_t mask128 = intrinsic_bits_to_bytes(mask16);
Run Code Online (Sandbox Code Playgroud)

或直接敷面膜:

int mask16 = 0b1010101010101010; 
__uint128_t v = ((__uint128_t)0x2828282828282828 << 64) | 0x2828282828282828;
__uint128_t w = intrinsic_bits_to_bytes_mask(v, mask16); // w = ((__uint128_t)0x2928292829282928 << 64) | 0x2928292829282928;

Run Code Online (Sandbox Code Playgroud)

c c++ sse bit-manipulation intrinsics

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

基于 BitMask 在数组中设置值的本质

是否有一个内在函数可以在输入数组中的所有位置设置单个值,其中相应位置在提供的 BitMask 中具有 1 位?

10101010 是位掩码

值为 121

它将设置位置 0,2,4,6 值为 121

c x86 bit-manipulation intel intrinsics

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

标签 统计

x86 ×5

avx ×3

c ×3

intrinsics ×3

sse ×3

assembly ×2

avx2 ×2

bit-manipulation ×2

simd ×2

basm ×1

c++ ×1

delphi ×1

icc ×1

intel ×1

optimization ×1

sse4 ×1

x86-64 ×1