__builtin_xxx指令学习【3】__builtin_popcount __builtin_popcountll
__builtin_popcount
是GCC和Clang编译器提供的一个内置函数,用于计算一个整数中二进制位为1的个数。该函数的使用背景是在一些位运算和计算机视觉等领域中,需要对二进制数据进行处理和分析,而二进制位为1的个数是一个常见的计算需求。
__builtin_popcount
的内部原理是使用CPU的指令集来实现计算。具体来说,当CPU支持POPCNT指令时,__builtin_popcount
会使用POPCNT指令来计算二进制位为1的个数;否则,__builtin_popcount
会使用一些位运算技巧来实现计算。在实现中,__builtin_popcount
会根据不同的CPU架构和编译器选项来选择最优的实现方式,从而提高计算效率。
__builtin_popcount
的弊端是可能会导致代码的可移植性问题。由于__builtin_popcount
是GCC和Clang编译器提供的一个内置函数,因此在使用__builtin_popcount
时,需要确保代码的可移植性,并且需要在代码中添加条件编译来处理不支持POPCNT指令的CPU。另外,由于__builtin_popcount
的实现依赖于CPU架构和编译器选项,因此在不同的平台和编译器下,__builtin_popcount
的性能可能会有所不同。在使用__builtin_popcount
时,需要进行性能测试,并根据实际情况选择最优的实现方式。
与之相似的是__builtin_popcountll
,用于计算一个64位整数中1的个数。
下面是一个demo
#include <iostream>
#include <chrono>
int main() {
auto start = std::chrono::high_resolution_clock::now();
int count = 0;
for (int i = 0; i < 100000000; ++i) {
count += __builtin_popcount(i);
}
auto end = std::chrono::high_resolution_clock::now();
std::cout << "Count: " << count << "\n";
std::cout << "Time: " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms\n";
return 0;
}
结果:
#include <iostream>
#include <chrono>
int main() {
auto start = std::chrono::high_resolution_clock::now();
long long count = 0;
for (long long i = 0; i < 100000000; ++i) {
count += __builtin_popcountll(i);
}
auto end = std::chrono::high_resolution_clock::now();
std::cout << "Count: " << count << "\n";
std::cout << "Time: " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms\n";
return 0;
}