如何在内存块上按位操作(C ++) [英] How to bitwise operate on memory block (C++)

查看:276
本文介绍了如何在内存块上按位操作(C ++)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有比使用for循环更好(更快/更有效)的方法来对大内存块执行按位运算?在查看完选项后,我注意到std有一个成员std::bitset,并且还想知道将较大的内存区域转换为位集而不更改其值是否更好(甚至可能),然后执行操作,然后将其类型切换回正常状态?

Is there a better (faster/more efficient) way to perform a bitwise operation on a large memory block than using a for loop? After looking it to options I noticed that std has a member std::bitset, and was also wondering if it would be better (or even possible) to convert a large region of memory into a bitset without changing its values, then perform the operations, and then switch its type back to normal?

编辑/更新:我认为union可能适用于此,以便为内存块分配int或其他内容的new数组,然后将其作为大的bitset进行操作.似乎可以根据此处所说的内容对整个集合进行操作: http ://www.cplusplus.com/reference/bitset/bitset/operators/.

Edit / update: I think union might apply here, such that the memory block is allocated a new array of int or something and then manipulated as a large bitset. Operations seem to be able to be done over the entire set based on what is said here: http://www.cplusplus.com/reference/bitset/bitset/operators/ .

推荐答案

通常,没有一种神奇的方法比for循环更快.但是,请记住以下几点,使编译器更容易优化循环:

In general, there is no magical way faster than a for loop. However, you can make it easier for the compiler to optimize the loop by keeping a few things in mind:

  1. 一次将最大的可用整数类型加载到内存中.但是,如果缓冲区的长度不能除以该整数类型的大小,则需要小心.
  2. 如果可能,请在一个循环迭代中对多个值进行操作-这将使向量化对于编译器更为简单.同样,您需要注意缓冲区长度.
  3. 如果循环要在短代码段上多次运行,请使用从下到下而不是向上计数的循环索引,并从数组长度中减去它-这使CPU的分支预测变量更容易计算了解发生了什么事.
  4. 您可以使用编译器提供的显式矢量扩展名,但这会使您的代码可移植性降低.
  5. 最终,您可以在汇编中编写循环并使用CPU提供的矢量指令,但这是完全不可移植的.
  6. [edit]另外,您可以使用OpenMP或类似的API在多个线程之间划分循环,但这只会在您对大量内存执行操作的情况下才会有所改善.

使用固定字节对内存进行异或运算的C99示例,假设long long为128位,缓冲区的开始对齐为16个字节,并且不考虑第3点.在两个内存缓冲区上的按位运算非常相似.

C99 example of xoring memory with a constant byte, assuming long long is 128-bit, the start of the buffer is aligned to 16 bytes, and without considering point 3. Bitwise operations on two memory buffers are very similar.

size_t len = ...;
char *buffer = ...;

size_t const loadd_per_i = 4
size_t iters = len / sizeof(long long) / loads_per_i;

long long *ptr = (long long *) buffer;
long long xorvalue = 0x5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5eLL;

// run in multiple threads if there are more than 4 MB to xor
#pragma omp parallel for if(iters > 65536)
for (size_t i = 0; i < iters; ++i) {
    size_t j = loads_per_i*i;
    ptr[j  ] ^= xorvalue;
    ptr[j+1] ^= xorvalue;
    ptr[j+2] ^= xorvalue;
    ptr[j+3] ^= xorvalue;
}

// finish long longs which don't align to 4
for (size_t i = iters * loads_per_i; i < len / sizeof(long long); ++i) {
    ptr[i] ^= xorvalue;
}

// finish bytes which don't align to long
for (size_t i = (len / sizeof(long long)) * sizeof(long long); i < len; ++i) {
    buffer[i] ^= xorvalue;
}

这篇关于如何在内存块上按位操作(C ++)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆