【发布时间】:2011-04-01 20:42:16
【问题描述】:
过去我不得不这样做很多次,但我从未对结果感到满意。
谁能建议一种将连续位数组从源复制到目标的快速方法,其中源和目标可能未在方便的处理器边界上对齐(右移)?
如果源和目标都没有对齐,问题可以很快变成只有其中一个没有对齐的问题(在第一个副本之后)。
作为一个起点,我的代码不可避免地最终看起来类似于以下内容(未经测试,忽略副作用,这只是一个即兴例子):
const char mask[8] = { 1, 3, 7, 15, 31, 63, 127, 255 };
/* Assume:
* - destination is already zeroed,
* - offsets are right shifts
* - bits to copy is big (> 32 say)
*/
int bitarray_copy(char * src, int src_bit_offset, int src_bit_len,
char * dst, int dst_bit_offset) {
if (src_bit_offset == dst_bit_offset) { /* Not very interesting */
} else {
int bit_diff_offset = src_bit_offset - dst_bit_offset; /* assume positive */
int loop_count;
char c;
char mask_val = mask[bit_diff_offset];
/* Get started, line up the destination. */
c = (*src++ << bit_diff_offset) | ((*src >> (8 - bit_diff_offset)) & mask_val);
c &= mask[8-dst_bit_offset];
*dst++ |= c;
src_bit_len -= 8 - dst_bit_offset;
loop_count = src_bit_len >> 3;
while (--loop_count >= 0)
* dst ++ = (*src++ << bit_diff_offset) | ((*src >> (8 - bit_diff_offset)) & mask_val);
/* Trailing tail copy etc ... */
if (src_bit_len % 8) /* ... */
}
}
(其实这个比我之前做的好,看起来还不错)
【问题讨论】:
-
将
struct(s) 与位字段一起使用并让编译器来做? :P -
这会如何改进?
-
这些位域是否重叠?能否将问题转化为简单应用 memcpy 即可解决的问题? Visual C++ 上的 memcpy 是高度优化的 (/ARCH:SSE2),GCC 和朋友至少确保在复制大块之前到达段落边界。