有没有一种更快的方法来按位连接两个整数? < >我的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; } #包括 #包括 int main() { std::uint32_t leftHalf=1; 标准:uint32_t rightshalf=2; std::uint64_t concatenated=((std::uint64_t)leftHalf
如果找到一种有效的方法将一个值的一部分(视为位集)复制到另一个值的一部分(视为位集),则可以额外提高速度。但我想这可能有点不太方便 顺便说一下,在下面的代码中,函数有没有一种更快的方法来按位连接两个整数? < >我的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; } #包括 #包括 int main() { std::uint32_t leftHalf=1; 标准:uint32_t rightshalf=2; std::uint64_t concatenated=((std::uint64_t)leftHalf,c++,performance,bitwise-operators,C++,Performance,Bitwise Operators,如果找到一种有效的方法将一个值的一部分(视为位集)复制到另一个值的一部分(视为位集),则可以额外提高速度。但我想这可能有点不太方便 顺便说一下,在下面的代码中,函数concat1在编译代码中比concat2短一个命令 #include <iostream> using namespace std; std::uint64_t concat1(const std::uint32_t& leftHalf, const std::uint32_t& rightHalf){
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;
}
如果你能找到一种有效的方法,将一个值的一部分(视为位集)复制到另一个值的一部分(视为位集)中,你可以额外提高速度。但我想这可能有点不妥 顺便说一下,在下面的代码中,函数
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;
}
综合这些信息,可以得出原始问题的以下答案: 这要视情况而定。而且,更快的方式很可能不会有什么不同。 根据周围的代码,可以使用以下技术:
- 可以将32位部分存储为数组中的两个元素,然后将该数组
存储为64位整数。()memcpy
- 根据32位值的存储方式,可以使用并行化,例如使用AVX命令()
最后,强烈建议使用一种方法(例如,
gcc-S
,一种探查器,如perf)来确定代码的哪些部分花费的时间最多。这些信息的组合将导致以下原始问题的答案:
这要视情况而定。而且,更快的方式很可能不会有什么不同。
根据周围的代码,可以使用以下技术:
- 可以将32位部分存储为数组中的两个元素,然后将该数组
存储为64位整数。()memcpy
- 根据32位值的存储方式,可以使用并行化,例如使用AVX命令()
最后,强烈建议使用一种方法(例如,
gcc-S
,一个探查器,如perf)来确定代码的哪些部分花费的时间最多。对gcc和CLANG使用-O2
和-O3
进行了尝试,两种编译器的结果都是相同的(GCC和CLANG-sal
与shl
和指令顺序之间存在细微差异)。即使使用选项-O2和-O3,concat2也少了一个mov操作。@UweJ,它们在Clang trunk上都给出了相同的asm:。通过值而不是引用传递可以节省一条额外的指令/两个指针取消引用:。GCC trunk给出了非常相似的结果。@chris和Brendan。感谢您的努力!我只尝试了一个GCC编译器。编译器的优化功能显然比我在代码上尝试的微优化有更大的影响。因此,我的尝试就是一个例子,说明为什么在许多(可能是大多数)代码中应该避免微优化案例。对GCC和CLANG使用-O2
和-O3
进行了尝试,两种编译器的结果都是相同的(GCC和CLANG-sal
与shl
和指令顺序之间存在细微差异)。即使使用选项-O2和-O3,concat2也少了一个mov操作。@UweJ,它们在Clang trunk上都给出了相同的asm:。通过值而不是引用传递可以节省一条额外的指令/两个指针取消引用:。GCC trunk给出了非常相似的结果。@chris和Brendan。感谢您的努力!我只尝试了一个GCC编译器。编译器的优化功能显然比我在代码上尝试的微优化有更大的影响。因此,我的尝试就是一个例子,说明为什么在许多(可能是大多数)代码中应该避免微优化案例。注释不用于扩展讨论;本次对话已经进行过。只需确保不会落入典型的优化陷阱。首先证明这是一个瓶颈。如果是,请首先尝试调整算法,以避免执行此操作。此操作极不可能是您的瓶颈。注释为not用于扩展讨论;本次对话已经结束。请确保不要落入典型的优化陷阱。首先证明这是一个瓶颈。如果是,请首先尝试并调整您的算法,以避免执行此操作。此操作极不可能是您的瓶颈。
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, DWORD PTR [rax]
mov eax, eax
or QWORD PTR [rbp-8], rax
mov rax, QWORD PTR [rbp-8]
pop rbp
ret
concat2(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
sal rax, 32
mov rdx, rax
mov rax, QWORD PTR [rbp-32]
mov eax, DWORD PTR [rax]
mov eax, eax
or rax, rdx
mov QWORD PTR [rbp-8], rax
mov rax, QWORD PTR [rbp-8]
pop rbp
ret