按位移memmove

什么是实现按位的最佳方式memmove ? 该方法应该采取额外的目的地和源的位偏移和计数应在比特太。

  • 我看到ARM提供了非标准_membitmove ,这不正是我需要的,但我找不到它的来源。
  • 绑定的bitset包含isc_bitstring_copy ,但效率不高
  • 我知道C标准库不提供这样的方法,但我也找不到任何提供类似方法的第三方代码。

  • 由于高级语言将最小单位提供为1字节,因此不会有标准功能为您提供此选项。 也许你可以找一个提供这些功能的第三方库,但是否则你将不得不为自己编码。


    假设“最好”意味着“最简单”,您可以逐个复制位。 从概念上讲,一个位的地址是一个对象(结构体),它具有指向内存中的一个字节的指针以及该字节中的一个位的索引。

    struct pointer_to_bit
    {
        uint8_t* p;
        int b;
    };
    
    void membitmovebl(
        void *dest,
        const void *src,
        int dest_offset,
        int src_offset,
        size_t nbits)
    {
        // Create pointers to bits
        struct pointer_to_bit d = {dest, dest_offset};
        struct pointer_to_bit s = {src, src_offset};
    
        // Bring the bit offsets to range (0...7)
        d.p += d.b / 8; // replace division by right-shift if bit offset can be negative 
        d.b %= 8; // replace "%=8" by "&=7" if bit offset can be negative
        s.p += s.b / 8;
        s.b %= 8;
    
        // Determine whether it's OK to loop forward
        if (d.p < s.p || d.p == s.p && d.b <= s.b)
        {
            // Copy bits one by one
            for (size_t i = 0; i < nbits; i++)
            {
                // Read 1 bit
                int bit = (*s.p >> s.b) & 1;
    
                // Write 1 bit
                *d.p &= ~(1 << d.b);
                *d.p |= bit << d.b;
    
                // Advance pointers
                if (++s.b == 8)
                {
                    s.b = 0;
                    ++s.p;
                }
                if (++d.b == 8)
                {
                    d.b = 0;
                    ++d.p;
                }
            }
        }
        else
        {
            // Copy stuff backwards - essentially the same code but ++ replaced by --
        }
    }
    

    如果你想编写一个针对速度进行了优化的版本,你将不得不按字节(或者更好的单词)进行复制,展开循环,并处理一些特殊情况( memmove做到这一点;你将不得不做更多的事情,因为你的功能更复杂)。

    PS哦,看到你调用isc_bitstring_copy效率低下,你可能想要速度优化。 您可以使用以下想法:

    单独开始复制比特,直到目标字节对齐( db == 0 )。 然后,很容易一次复制8位,做一些小事。 这样做直到剩下少于8位才能复制; 然后继续逐个拷贝位。

    // Copy 8 bits from s to d and advance pointers
    *d.p = *s.p++ >> s.b;
    *d.p++ |= *s.p << (8 - s.b);
    

    PPS哦,看到你对将要使用的代码的评论,你并不需要实现所有版本(字节/半字/字,大/小端)。 你只需要最简单的一个 - 使用单词( uint32_t )的单词。


    这是部分实现(未测试)。 有明显的效率和可用性改进。

    拷贝n字节从srcdest (不重叠src ),并在移位比特dest向右通过bit位,0 <= bit <= 7。这假定至少显著比特在字节的权

    void memcpy_with_bitshift(unsigned char *dest, unsigned char *src, size_t n, int bit)
    {
      int i;
    
      memcpy(dest, src, n);
    
      for (i = 0; i < n; i++) {
        dest[i] >> bit;
      }
    
      for (i = 0; i < n; i++) {
        dest[i+1] |= (src[i] << (8 - bit));
      }
    }
    

    一些改进:

  • 不要覆盖dest开头的第一个bit位。
  • 合并循环
  • 有办法复制一些不能被8整除的位
  • 在char中修复> 8位
  • 链接地址: http://www.djcxy.com/p/15845.html

    上一篇: Bitwise memmove

    下一篇: Safari image overlapping issue