c++ - 如何对内存块进行按位操作(C++)

标签 c++ memory bit-manipulation bitwise-operators bitset

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

编辑/更新:我认为 union 可能适用于此,这样内存块就会分配一个 new 数组 int 或其他东西然后作为大型 bitset 进行操作。根据这里所说的,操作似乎可以在整个集合上完成:http://www.cplusplus.com/reference/bitset/bitset/operators/ .

最佳答案

一般来说,没有比 for 循环更快的神奇方法了。但是,您可以通过记住以下几点使编译器更容易优化循环:

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

C99 内存与常量字节异或的示例,假设 long long 是 128 位,缓冲区的开始对齐到 16 字节,并且不考虑第 3 点。两个内存缓冲区的按位操作非常相似。

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++ - 如何对内存块进行按位操作(C++),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21334021/

相关文章:

c++ - 在 Visual Studio 中直接调用 MATLAB(多线程)

c++ - 将数据从一个线程传递到另一个线程的最快方法

php - Magento 尝试分配过多的内存

java - 如何使用 Java 获取 JVM xmxBytes 指标

javascript - 如何查找内存泄漏并调试 jquery/javascript 应用程序?

algorithm - 了解具有位移位和 XOR 的五维 DP?

c++ - 初始化 COM 对象/将 VB 代码转换为 C++

c++ - 在接口(interface)中使用 const 是否有意义?

c++ - 在 32 位字位模式中找到 "edges"

如果位移太多,Javascript 数字将重置为 0