Bitwise memmove
实现按位memmove
的最佳方法是什么? 该方法应该采用额外的目标和源位偏移,并且计数也应该是位。
- 我看到ARM提供了一个非标准的
_membitmove
,它正是我所需要的,但我找不到它的来源。 - Bind的bitset包括
isc_bitstring_copy
,但效率不高 - 我知道C标准库没有提供这样的方法,但我也找不到提供类似方法的任何第三方代码。
由于Highlevel语言提供的最小单位为1 Byte,因此没有标准函数可以为您提供此选项。 也许你可以寻找提供这些function的第三方库,但你必须自己编写代码。
假设“最佳”意味着“最简单”,您可以逐个复制位。 从概念上讲,位的地址是一个对象(结构),它具有指向内存中字节的指针和字节中位的索引。
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) dp += db / 8; // replace division by right-shift if bit offset can be negative db %= 8; // replace "%=8" by "&=7" if bit offset can be negative sp += sb / 8; sb %= 8; // Determine whether it's OK to loop forward if (dp < sp || dp == sp && db <= sb) { // Copy bits one by one for (size_t i = 0; i < nbits; i++) { // Read 1 bit int bit = (*sp >> sb) & 1; // Write 1 bit *dp &= ~(1 << db); *dp |= bit << db; // Advance pointers if (++sb == 8) { sb = 0; ++sp; } if (++db == 8) { db = 0; ++dp; } } } else { // Copy stuff backwards - essentially the same code but ++ replaced by -- } }
如果你想编写一个针对速度优化的版本,你将不得不按字节(或更好,单词)进行复制,展开循环,并处理一些特殊情况( memmove
会这样做;你必须做更多,因为你的function更复杂)。
PS哦,看到你调用isc_bitstring_copy
效率低下,你可能想要速度优化。 您可以使用以下想法:
单独开始复制位,直到目标字节对齐( db == 0
)。 然后,很容易一次复制8位,做一些小事。 这样做直到剩下少于8位复制; 然后继续逐个复制位。
// Copy 8 bits from s to d and advance pointers *dp = *s.p++ >> sb; *d.p++ |= *sp << (8 - sb);
PPS哦,看到你对将要使用代码的评论,你真的不需要实现所有版本(byte / halfword / word,big / little-endian); 你只想要最简单的一个 - 使用单词( uint32_t
)。
这是部分实现(未测试)。 有明显的效率和可用性改进。
将src
n
个字节复制到dest
(不重叠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位