相关疑难解决方法(0)

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

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

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

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

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

c++ boolean bit-manipulation bit-packing

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

将屏蔽位移到lsb

当你and使用掩码的某些数据时,你会得到一些与数据/掩码大小相同的结果.我想要做的是取结果中的掩码位(掩码中有1)并将它们向右移动,使它们彼此相邻,我可以对它们执行CTZ(计数尾随零) .

我不知道如何命名这样的程序,所以谷歌让我失望.该操作最好不应该是循环解决方案,这必须尽可能快地操作.

这是一个用MS Paint制作的令人难以置信的图像. 在此输入图像描述

c c++ bitmask

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

如何在位图中的位之间插入零?

我有一些性能很重的代码执行位操作.它可以简化为以下明确定义的问题:

给定一个13位位图,构造一个26位位图,其中包含在偶数位置间隔的原始位.

为了显示:

0000000000000000000abcdefghijklm (input, 32 bits)
0000000a0b0c0d0e0f0g0h0i0j0k0l0m (output, 32 bits)
Run Code Online (Sandbox Code Playgroud)

我目前在C中以下列方式实现它:

if (input & (1 << 12))
    output |= 1 << 24;
if (input & (1 << 11))
    output |= 1 << 22;
if (input & (1 << 10))
    output |= 1 << 20;
...
Run Code Online (Sandbox Code Playgroud)

我的编译器(MS Visual Studio)将其转换为以下内容:

test        eax,1000h
jne         0064F5EC
or          edx,1000000h
... (repeated 13 times with minor differences in constants)
Run Code Online (Sandbox Code Playgroud)

我想知道我是否可以更快地完成任务.我想用C语言编写代码,但是可以切换到汇编语言.

  • 我可以使用一些MMX/SSE指令一次处理所有位吗?
  • 也许我可以使用乘法?(乘以0x11111111或其他一些神奇的常数)
  • 使用条件设置指令(SETcc)而不是条件跳转指令会更好吗?如果是,我如何让编译器为我生成这样的代码?
  • 还有其他想法如何让它更快?
  • 任何想法如何进行逆位图转换(我必须实现它,位不太重要)?

c optimization assembly bit-manipulation

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

将32 0/1值打包到单个32位变量的位中的最快方法是什么?

我正在使用x86或x86_64机器.我有一个数组unsigned int a[32],其所有元素的值都为0或1.我想设置单个变量,unsigned int b以便(b >> i) & 1 == a[i]为所有32个元素保持a.我在Linux上使用GCC(我猜不应该这么做).

在C中执行此操作的最快方法是什么?

c c++ performance bit-manipulation

10
推荐指数
5
解决办法
1413
查看次数

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

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

像 PEXT 这样的汇编指令实际上有什么用途?

我观看了有关十大最疯狂汇编语言指令的 YouTube 视频,其中一些指令对我来说没有明显的应用。像这样的东西有什么意义PEXT,它只取第二个参数中与第一个参数中的 1 索引相匹配的位?编译器如何知道何时使用该指令?关于无进位乘法的相同/相似问题。

免责声明:我对汇编语言知之甚少甚至一无所知。也许我应该读一下它!

我希望这个问题适合 stackoverflow。

x86 assembly bit-manipulation bmi

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

如何有效地将两个16位字组合成一个32位字?

我必须将两个16位字组合成一个32位字数百次,这需要很多计算能力.我想找到一种更有效的方法来做到这一点.

我有2个16位字,名为A和B.我想要一个名为C的32位字.A中的位应复制到C中的偶数位.B中的位应复制到奇数位中. C.例如:A:0b0000000000000000 B:0b1111111111111111处理后的C应为0b10101010101010101010101010101010.

我目前的解决方案如下:

for (i = 0; i < 32; i+=2)
{
    C |=  (A & (1 << (i/2))) << (i/2);
    C |=  (B & (1 << (i/2))) << (i/2 + 1);
}
Run Code Online (Sandbox Code Playgroud)

当我有几百个C要处理时,这个解决方案需要花费太多时间.我正在寻找一个更好的!

补充:该程序在TriCore上运行.我别无选择,只能以这种方式处理数据,因为AB和C之间的这种关系是由协议定义的.

谢谢!

c embedded performance bitwise-operators

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

不使用BMI2的便携式有效替代PDEP?

英特尔位操作指令集2(BMI2)中的并行存款指令(PDEP)的文档描述了该指令的以下串行实现(类似C的伪代码):

U64 _pdep_u64(U64 val, U64 mask) {
  U64 res = 0;
  for (U64 bb = 1; mask; bb += bb) {
    if (val & bb)
      res |= mask & -mask;
    mask &= mask - 1;
  }
  return res;
}
Run Code Online (Sandbox Code Playgroud)

另请参阅英特尔的pdepinsn参考手册.

该算法是O(n),其中n是设置位的数量mask,这显然具有O(k)的最坏情况,其中k是总的位数mask.

更有效的最坏情况算法是否可行?

是否有可能制作一个更快的版本,假设val最多有一个位设置,即等于0或等于0到63之间的1<<r某个值r

algorithm x86 assembly bit-manipulation bmi

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