> 文章列表 > __builtin_xxx指令学习【3】__builtin_popcount __builtin_popcountll

__builtin_xxx指令学习【3】__builtin_popcount __builtin_popcountll

__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;
}