相关疑难解决方法(0)

使用单个乘法提取位

我看到在使用了一个有趣的技术,答案另一个问题,并想好一点理解.

我们给出了一个无符号的64位整数,我们对以下几位感兴趣:

1.......2.......3.......4.......5.......6.......7.......8.......
Run Code Online (Sandbox Code Playgroud)

具体来说,我们希望将它们移到前八位,如下所示:

12345678........................................................
Run Code Online (Sandbox Code Playgroud)

我们不关心指示的位的值.,并且不必保留它们.

溶液是屏蔽掉不需要的位,并且乘以结果0x2040810204081.事实证明,这就是诀窍.

这种方法有多普遍?这种技术可以用来提取任何比特子集吗?如果不是,如何判断该方法是否适用于特定的位组?

最后,如何找到(a?)正确的乘数来提取给定的位?

c bit-manipulation multiplication

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

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
查看次数

如何解交织比特(UnMortonizing?)

从32位int解交织比特的最有效方法是什么?对于这种特殊情况,我只关注奇数位,尽管我确信将两个集合的任何解决方案概括为简单.

例如,我想转换0b010001010b1011.什么是最快的方式?

编辑:

在这个应用程序中,我可以保证偶数位都是零.我可以利用这个事实来提高速度或减少空间吗?

bit-manipulation z-order-curve

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

如何用8个bool值创建一个字节(反之亦然)?

我有8个bool变量,我想将它们"合并"成一个字节.

有一个简单/首选的方法来做到这一点?

相反,如何将一个字节解码为8个独立的布尔值?

我认为这不是一个不合理的问题,但由于我无法通过谷歌找到相关文档,它可能是另一个"非你所有直觉都是错误的"案例.

c++ boolean bit-manipulation bit-packing

20
推荐指数
4
解决办法
2万
查看次数

为什么 RISC-V SB 和 UJ 指令类型以这种方式编码?

我正在读一本书“计算机组织和设计 RISC-V 版”,我遇到了 SB 和 UJ 指令类型的编码。

我上面提到的那些类型具有奇怪的编码立即字段。

SB 类型将立即数字段分成两部分。这是有道理的,因为所有指令编码都必须相似。但我不明白为什么下面的直接字段以这种方式编码。

imm[12, 10:5], imm[4:1, 11]
Run Code Online (Sandbox Code Playgroud)

代替

imm[11:5], imm[4:0]
Run Code Online (Sandbox Code Playgroud)

UJ 类型也有这个奇怪的编码立即字段

imm[20,10:1,11,19:12]
Run Code Online (Sandbox Code Playgroud)

代替

imm[19:0]
Run Code Online (Sandbox Code Playgroud)

谁能解释一下?

assembly encoding instruction-set machine-code riscv

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

如何对像素数据进行位条带化处理?

我有3个缓冲区,包含在32位处理器上运行的R,G,B位数据.

我需要以下列方式组合三个字节:

R[0] = 0b r1r2r3r4r5r6r7r8
G[0] = 0b g1g2g3g4g5g6g7g8
B[0] = 0b b1b2b3b4b5b6b7b8

int32_t Out = 0b r1g1b1r2g2b2r3g3 b3r4g4b4r5g5b5r6 g6b6r7g7b7r8g8b8 xxxxxxxx
Run Code Online (Sandbox Code Playgroud)

其中xxxxxxxx继续到缓冲区中的每个下一个字节.

我正在寻找一种最佳的组合方式.我的方法绝对没有效率.

这是我的方法

static void rgbcombineline(uint8_t line)
{
    uint32_t i, bit;
    uint8_t bitMask, rByte, gByte, bByte;
    uint32_t ByteExp, rgbByte;
    uint8_t *strPtr = (uint8_t*)&ByteExp;

    for (i = 0; i < (LCDpixelsCol / 8); i++)
    {
        rByte = rDispbuff[line][i];
        gByte = gDispbuff[line][i];
        bByte = bDispbuff[line][i];

        bitMask = 0b00000001;
        ByteExp = 0;
        for(bit = 0; bit < 8; bit++)
        {
            rgbByte …
Run Code Online (Sandbox Code Playgroud)

c bit-manipulation interleave

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

如何取消设置最右边的 N 个设置位

有一个相对知名的技巧可以取消设置最右边的一个位:

y = x & (x - 1) // 0b001011100 & 0b001011011 = 0b001011000 :)
Run Code Online (Sandbox Code Playgroud)

我发现自己有一个紧密的循环来清除最右边的 n 位,但是有更简单的代数技巧吗?

假设 n 相对较大(对于 64 位整数,n 必须小于 64,但通常约为 20-30)。

// x = 0b001011100 n=2
for (auto i=0; i<n; i++) x &= x - 1;
// x = 0b001010000
Run Code Online (Sandbox Code Playgroud)

我翻阅了 TAOCP Vol4 几次,但找不到任何灵感。

也许有一些硬件支持?

bit-manipulation intrinsics integer-arithmetic

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

在一个字中间隔位的快速方法是什么?

我在64位寄存器的低位部分有一个32位值;顶部部分是 0。让我们X用信息来表示一个位,并用从 LSB 到 MSB 列出的位来表示,如下所示:

X X X  ...  X 0 0 0 0 ... 0
Run Code Online (Sandbox Code Playgroud)

现在,我想用信息“间隔”这些位,这样我就有了

X 0 X 0 X 0 ... X 0
Run Code Online (Sandbox Code Playgroud)

(或者如果你想把 0 放在前面,那么

0 X 0 X 0 X 0 ... X
Run Code Online (Sandbox Code Playgroud)

也很好。)

有什么快速的方法可以做到这一点?

与多 CPU 架构相关的答案会很好,但特定于 Intel x86_64 和/或 nVIDIA Pascal SM 的答案将是最相关的。

performance bitwise-operators

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