如何解决有没有一种更快的方法来按位连接两个整数?
对于我的C ++程序,我想将两个32位无符号整数按位连接为一个64位无符号整数。已经多次问过类似的问题,答案大多与此相似:
#include <cstdint>
#include <iostream>
int main()
{
std::uint32_t leftHalf = 1;
std::uint32_t rightHalf = 2;
std::uint64_t concatenated = ((std::uint64_t) leftHalf << 32) | secondHalf;
std::cout << "left=" << leftHalf << " and right=" << rightHalf << " concatenated into " << concatenated << std::endl;
}
由于我必须在程序中执行很多串联,因此我需要它非常有效。使用强制转换,移位和按位|,似乎可以使另一种技术(例如使用memcpy)更快。
连接两个整数是否比使用强制转换,移位和按位| |更快?
出于完整性考虑,我的 not 编译方法是
#include <cstdint>
#include <iostream>
int main()
{
std::uint32_t leftHalf = 1;
std::uint32_t rightHalf = 2;
std::uint64_t concatenated;
std::uint32_t *halfIt = &concatenated;
*halfIt = leftHalf;
++halfIt;
*halfIt = rightHalf;
std::cout << "left=" << leftHalf << " and right=" << rightHalf << " concatenated into " << concatenated << std::endl;
}
解决方法
如果找到了一种将值的一部分(视为位集)复制到另一个值的一部分(视为位集)中的有效方法,则可以进一步提高速度。但是我想这会有点骇人听闻。
顺便说一下,在下面的代码中,函数concat1
在编译后的代码中比concat2
短一个命令。
#include <iostream>
using namespace std;
std::uint64_t concat1(const std::uint32_t& leftHalf,const std::uint32_t& rightHalf){
std::uint64_t concatenated = leftHalf;
concatenated <<= 32;
concatenated |= rightHalf;
return concatenated;
}
std::uint64_t concat2(const std::uint32_t& leftHalf,const std::uint32_t& rightHalf){
std::uint64_t concatenated = (static_cast<std::uint64_t>(leftHalf) << 32) | rightHalf;
return concatenated;
}
int main() {
cout << concat1(1,2) <<std::endl;
cout << concat2(1,2) <<std::endl;
}
您可以在例如https://godbolt.org/。函数concat1
比mov
少执行一次concat2
操作。但是差异将很小。我估计约占运行时间的5%;
concat1(unsigned int const&,unsigned int const&):
push rbp
mov rbp,rsp
mov QWORD PTR [rbp-24],rdi
mov QWORD PTR [rbp-32],rsi
mov rax,QWORD PTR [rbp-24]
mov eax,DWORD PTR [rax]
mov eax,eax
mov QWORD PTR [rbp-8],rax
sal QWORD PTR [rbp-8],32
mov rax,QWORD PTR [rbp-32]
mov eax,eax
or QWORD PTR [rbp-8],rax
mov rax,QWORD PTR [rbp-8]
pop rbp
ret
concat2(unsigned int const&,eax
sal rax,32
mov rdx,eax
or rax,rdx
mov QWORD PTR [rbp-8],QWORD PTR [rbp-8]
pop rbp
ret
,
discussion的组合信息导致对原始问题的以下回答:
这取决于。另外,更快的方法很可能不会有所作为。
根据周围的代码,可以使用以下技术:
- 一个人可以将32位部分存储为数组中的两个元素,然后
memcpy
将该数组存储为64位整数。 (suggested by NathanOliver) - 根据32位值的存储方式,可以使用并行化,例如:使用AVX命令(suggested by sgorozco)
但这可能没什么作用
其他操作(例如从内存/缓存中单次获取数据)比 multiple 按位操作(pointed out by JulianH)花费的运行时间更多。因此,在当前的CPU设计中,按位运算可能会在加载操作期间运行,下一条指令将等待耗时的加载操作完成。
最后,强烈建议使用一种方法(例如https://godbolt.org/,gcc -S
,性能分析器(例如perf))来确定哪些部分代码花费的时间最多。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。