我考虑如何对2个字节的数组进行有效的XORing。
我将此字节数组定义为unsigned char *
我认为将它们作为uint64_t
异或会更快。是真的吗
如何在XORing循环内有效地将unsigned char *
转换为此uint64_t *
?如果字节数组%8的长度不为0,如何填充最后一个字节?
这是XORs字节数组的当前代码,但每个字节(无符号字符)分别为:
unsigned char *bitwise_xor(const unsigned char *A_Bytes_Array, const unsigned char *B_Bytes_Array, const size_t length) {
unsigned char *XOR_Bytes_Array;
// allocate XORed bytes array
XOR_Bytes_Array = malloc(sizeof(unsigned char) * length);
// perform bitwise XOR operation on bytes arrays A and B
for(int i=0; i < length; i++)
XOR_Bytes_Array[i] = (unsigned char)(A_Bytes_Array[i] ^ B_Bytes_Array[i]);
return XOR_Bytes_Array;
}
好的,与此同时,我尝试过这种方式。我的bytes_array相当大(rgba位图4 * 1440 * 900?)。
static uint64_t next64bitsFromBytesArray(const unsigned char *bytesArray, const int i) {
uint64_t next64bits = (uint64_t) bytesArray[i+7] | ((uint64_t) bytesArray[i+6] << 8) | ((uint64_t) bytesArray[i+5] << 16) | ((uint64_t) bytesArray[i+4] << 24) | ((uint64_t) bytesArray[i+3] << 32) | ((uint64_t) bytesArray[i+2] << 40) | ((uint64_t) bytesArray[i+1] << 48) | ((uint64_t)bytesArray[i] << 56);
return next64bits;
}
unsigned char *bitwise_xor64(const unsigned char *A_Bytes_Array, const unsigned char *B_Bytes_Array, const size_t length) {
unsigned char *XOR_Bytes_Array;
// allocate XORed bytes array
XOR_Bytes_Array = malloc(sizeof(unsigned char) * length);
// perform bitwise XOR operation on bytes arrays A and B using uint64_t
for(int i=0; i<length; i+=8) {
uint64_t A_Bytes = next64bitsFromBytesArray(A_Bytes_Array, i);
uint64_t B_Bytes = next64bitsFromBytesArray(B_Bytes_Array, i);
uint64_t XOR_Bytes = A_Bytes ^ B_Bytes;
memcpy(XOR_Bytes_Array + i, &XOR_Bytes, 8);
}
return XOR_Bytes_Array;
}
更新:(解决此问题的第二种方法)
unsigned char *bitwise_xor64(const unsigned char *A_Bytes_Array, const unsigned char *B_Bytes_Array, const size_t length) {
const uint64_t *aBytes = (const uint64_t *) A_Bytes_Array;
const uint64_t *bBytes = (const uint64_t *) B_Bytes_Array;
unsigned char *xorBytes = malloc(sizeof(unsigned char)*length);
for(int i = 0, j=0; i < length; i +=8) {
uint64_t aXORbBytes = aBytes[j] ^ bBytes[j];
//printf("a XOR b = 0x%" PRIx64 "\n", aXORbBytes);
memcpy(xorBytes + i, &aXORbBytes, 8);
j++;
}
return xorBytes;
}
最佳答案
所以我做了一个实验:
#include <stdlib.h>
#include <stdint.h>
#ifndef TYPE
#define TYPE uint64_t
#endif
TYPE *
xor(const void *va, const void *vb, size_t l)
{
const TYPE *a = va;
const TYPE *b = vb;
TYPE *r = malloc(l);
size_t i;
for (i = 0; i < l / sizeof(TYPE); i++) {
*r++ = *a++ ^ *b++;
}
return r;
}
使用基本优化的clang为
uint64_t
和uint8_t
进行了编译。在这两种情况下,编译器都会对此进行向量化。区别在于uint8_t版本具有在l
不是8的倍数时处理的代码。因此,如果我们添加代码以处理大小不是8的倍数的代码,则可能会得到等效的生成代码。此外,64位版本还展开了几次循环并具有处理该代码的代码,因此对于足够大的阵列,您可能会在此处获得百分之几的收益。另一方面,在足够大的阵列上,您将受到内存限制,并且xor操作无关紧要。您确定编译器不会处理此问题吗?这是一种微优化,只有在测量事物时才有意义,然后您就不需要问哪个更快。
关于c - C中使用64位而不是8位的按位XOR,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40104897/