优化bitset操作
Optimizing bitset operation
我希望优化这段代码。BitSetPattern
的大小为512,BitSetOut
的长度为2048。
基本上这段代码所做的,它采用4个BitSetPatterns并通过连接它们创建一个BitSetOut。每复制一个比特要花太多时间。
我认为OR和SHIFT可以解决这种情况,但是操作符只能取相同长度的位集。也无法用较小的bitset初始化bitset,并将剩余的位填充为0。
unsigned outputIter = 0;
BitSetPattern output(0);
for (int i = 3; i >= 0; i--)
{
BitSetOut currentInput = this->input[ i ]->getOutput();
for (unsigned j = 0; j < currentInput.size(); j++)
{
output[ outputIter ] = currentInput[ j ];
outputIter++;
}
}
return output;
我已经对代码进行了概要分析,这是一个花费太多时间的方法
这是一个非常不安全的解决方案,您应该不要使用:
assert (sizeof(output) == output.size() / 8);
assert ((output.size() / 8) == 0);
int offset = 0;
for (int i = 3; i >= 0; --i)
{
auto const sz = input[i].size();
assert ((sz % 8) == 0);
assert (offset + (sz / 8) <= output.size());
memcpy (((char*)&(output)) + offset, (char*)&(input[i]), sz / 8);
offset += sz / 8;
}
基本上,这试图确保安全,并确保bitset中除了位(没有填充,对齐,可能大小甚至压缩位)之外没有其他内容。然后将它们作为一个整体复制。
在标准(AFAIK)中没有任何东西保证这将工作。它甚至可能不适用于现有的实现,但我相信它"应该"适用于直接的std::bitset
实现。
它可能可以加快复制部分。因为你知道你的数据的大小,它是非常小的,你可以直接写SSE或甚至AVX内部函数,将那些512位的源地址复制到目标地址。
还有三种方法可以尝试:
如果你绝对确定你的大小保持不变(例如2048和512位),使用常数值并放弃算术和断言。这个可能有帮助,这取决于你的编译器如何处理
memcpy
(一些编译器在某些情况下优化它,例如,如果大小是常数和字长的倍数,等等)确保您的位缓冲区分配在缓存行大小的倍数(例如64字节)的地址上。这是为了确保你不会触及多余的缓存行。
你可以尝试帮助内存"预取器"通过触摸下一个输入缓冲区在每次迭代。例如:
char * output_ptr = (char *)&output; char * input_ptrs [4] = {(char*)&(input[0]), (char*)&(input[1]), ...}; volatile char dummy = 0; dummy += input_ptrs[2][0]; // prefetch the next one memcpy (output_ptr + 0, input_ptrs[3], 64); // copy dummy += input_ptrs[1][0]; // prefetch the next one memcpy (output_ptr + 64, input_ptrs[2], 64); // copy dummy += input_ptrs[0][0]; // prefetch the next one memcpy (output_ptr + 128, input_ptrs[1], 64); // copy memcpy (output_ptr + 192, input_ptrs[0], 64); // copy
相关文章:
- 为什么在popback()操作之后,它仍然打印完整的矢量
- 重载操作程序时出错>>用于类中的字符串 memebr
- 对字符串进行位操作
- 我可以在 C++ 中的函数体之外进行操作吗?
- MPI突然停止了对多个核心的操作
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 对字符数组中的元素执行逐位操作
- 如何在directx/c++中进行平移/缩放操作
- 逐位操作的隐式类型转换
- 为什么一个向量上的多线程操作很慢
- 排序时无法执行交换操作.我做的时候它会崩溃.为什么
- 位移操作和位掩码未检测到重复字符
- 如何进行特定的位操作?
- 当我们进行一些操作时,应该使用什么'std::string'或'std::stringstream'?
- 字符串操作 - 字符计数
- 此代码中的操作流程是什么?C/C++.
- 复制和交换习惯用法与移动操作之间的交互
- C++新手关于使用字符串的Bitset操作
- 优化bitset操作
- c++中的Bitset操作