gpt4 book ai didi

c - 什么是复制未对齐位数组的高效算法?

转载 作者:太空狗 更新时间:2023-10-29 17:21:01 25 4
gpt4 key购买 nike

过去我不得不这样做很多次,但我对结果从未感到满意。

谁能建议一种将连续位数组从源复制到目标的快速方法,其中源和目标可能未在方便的处理器边界上对齐(右移)?

如果源和目标都没有对齐,问题可以很快变成只有其中一个没有对齐(在第一个副本之后)。

作为起点,我的代码最终不可避免地看起来像下面这样(未经测试,忽略副作用,这只是一个即兴的例子):

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) /* ... */
}
}

(其实这个比我之前做的好多了,看起来还不错)

最佳答案

这就是我最终所做的。 (编辑 于 2014 年 8 月 21 日更改为单个位复制错误。)

#include <limits.h>
#include <string.h>
#include <stddef.h>

#define PREPARE_FIRST_COPY() \
do { \
if (src_len >= (CHAR_BIT - dst_offset_modulo)) { \
*dst &= reverse_mask[dst_offset_modulo]; \
src_len -= CHAR_BIT - dst_offset_modulo; \
} else { \
*dst &= reverse_mask[dst_offset_modulo] \
| reverse_mask_xor[dst_offset_modulo + src_len]; \
c &= reverse_mask[dst_offset_modulo + src_len]; \
src_len = 0; \
} } while (0)


static void
bitarray_copy(const unsigned char *src_org, int src_offset, int src_len,
unsigned char *dst_org, int dst_offset)
{
static const unsigned char mask[] =
{ 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
static const unsigned char reverse_mask[] =
{ 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
static const unsigned char reverse_mask_xor[] =
{ 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00 };

if (src_len) {
const unsigned char *src;
unsigned char *dst;
int src_offset_modulo,
dst_offset_modulo;

src = src_org + (src_offset / CHAR_BIT);
dst = dst_org + (dst_offset / CHAR_BIT);

src_offset_modulo = src_offset % CHAR_BIT;
dst_offset_modulo = dst_offset % CHAR_BIT;

if (src_offset_modulo == dst_offset_modulo) {
int byte_len;
int src_len_modulo;
if (src_offset_modulo) {
unsigned char c;

c = reverse_mask_xor[dst_offset_modulo] & *src++;

PREPARE_FIRST_COPY();
*dst++ |= c;
}

byte_len = src_len / CHAR_BIT;
src_len_modulo = src_len % CHAR_BIT;

if (byte_len) {
memcpy(dst, src, byte_len);
src += byte_len;
dst += byte_len;
}
if (src_len_modulo) {
*dst &= reverse_mask_xor[src_len_modulo];
*dst |= reverse_mask[src_len_modulo] & *src;
}
} else {
int bit_diff_ls,
bit_diff_rs;
int byte_len;
int src_len_modulo;
unsigned char c;
/*
* Begin: Line things up on destination.
*/
if (src_offset_modulo > dst_offset_modulo) {
bit_diff_ls = src_offset_modulo - dst_offset_modulo;
bit_diff_rs = CHAR_BIT - bit_diff_ls;

c = *src++ << bit_diff_ls;
c |= *src >> bit_diff_rs;
c &= reverse_mask_xor[dst_offset_modulo];
} else {
bit_diff_rs = dst_offset_modulo - src_offset_modulo;
bit_diff_ls = CHAR_BIT - bit_diff_rs;

c = *src >> bit_diff_rs &
reverse_mask_xor[dst_offset_modulo];
}
PREPARE_FIRST_COPY();
*dst++ |= c;

/*
* Middle: copy with only shifting the source.
*/
byte_len = src_len / CHAR_BIT;

while (--byte_len >= 0) {
c = *src++ << bit_diff_ls;
c |= *src >> bit_diff_rs;
*dst++ = c;
}

/*
* End: copy the remaing bits;
*/
src_len_modulo = src_len % CHAR_BIT;
if (src_len_modulo) {
c = *src++ << bit_diff_ls;
c |= *src >> bit_diff_rs;
c &= reverse_mask[src_len_modulo];

*dst &= reverse_mask_xor[src_len_modulo];
*dst |= c;
}
}
}
}

关于c - 什么是复制未对齐位数组的高效算法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3534535/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com