__builtin_xxx指令学习【5】__builtin_bswap16/32/64

2023-05-16

__builtin_bswap16/32/64是GCC和Clang编译器提供的内置函数,用于交换一个整数的字节顺序。其中,__builtin_bswap16用于交换一个16位整数的字节顺序,__builtin_bswap32用于交换一个32位整数的字节顺序,__builtin_bswap64用于交换一个64位整数的字节顺序。这些函数的使用背景是在一些网络编程和底层编程中,需要对字节序进行处理和转换,而交换字节顺序是一个常见的操作。

__builtin_bswap16/32/64的内部原理是使用CPU的指令集来实现交换。具体来说,当CPU支持BSWAP指令时,__builtin_bswap16/32/64会使用BSWAP指令来实现交换;否则,__builtin_bswap16/32/64会使用一些位运算技巧来实现交换。在实现中,__builtin_bswap16/32/64会根据不同的CPU架构和编译器选项来选择最优的实现方式,从而提高交换效率。

__builtin_bswap16/32/64的弊端是可能会导致代码的可移植性问题。由于__builtin_bswap16/32/64是GCC和Clang编译器提供的内置函数,因此在使用__builtin_bswap16/32/64时,需要确保代码的可移植性,并且需要在代码中添加条件编译来处理不支持BSWAP指令的CPU。另外,由于__builtin_bswap16/32/64的实现依赖于CPU架构和编译器选项,因此在不同的平台和编译器下,__builtin_bswap16/32/64的性能可能会有差异。

下面给出一个demo,这里为了平台兼容性我们也实现了不支持__builtin_bswap的对应的函数。

在这个代码中,我们首先使用defined(__GNUC__) || defined(__clang__)来判断当前编译器是否是GCC或Clang。如果是,我们再使用defined(__x86_64__) || defined(__i386__)来判断当前CPU是否是x86或x86-64架构。如果是,我们就定义BSWAP_SUPPORTED宏,表示当前CPU支持BSWAP指令。

接下来,我们使用#ifdef BSWAP_SUPPORTED来判断当前CPU是否支持BSWAP指令。

#include <iostream>
#include <chrono>
#include <cstdint>

#if defined(__GNUC__) || defined(__clang__)
    #if defined(__x86_64__) || defined(__i386__)
        #define BSWAP_SUPPORTED
    #endif
#endif

#ifdef BSWAP_SUPPORTED
    #define bswap16 __builtin_bswap16
    #define bswap32 __builtin_bswap32
    #define bswap64 __builtin_bswap64
#else
    template<typename T>
    T bswap(T value) {
        static_assert(std::is_integral<T>::value, "bswap only works with integral types");
        uint8_t* ptr = reinterpret_cast<uint8_t*>(&value);
        for (size_t i = 0, j = sizeof(T) - 1; i < j; ++i, --j) {
            std::swap(ptr[i], ptr[j]);
        }
        return value;
    }

    template<typename T>
    T bswap16(T value) {
        static_assert(std::is_integral<T>::value, "bswap16 only works with integral types");
        uint16_t result = bswap(static_cast<uint16_t>(value));
        return static_cast<T>(result);
    }

    template<typename T>
    T bswap32(T value) {
        static_assert(std::is_integral<T>::value, "bswap32 only works with integral types");
        uint32_t result = bswap(static_cast<uint32_t>(value));
        return static_cast<T>(result);
    }

    template<typename T>
    T bswap64(T value) {
        static_assert(std::is_integral<T>::value, "bswap64 only works with integral types");
        uint64_t result = bswap(static_cast<uint64_t>(value));
        return static_cast<T>(result);
    }
#endif

int main() {
    uint16_t a = 0x1234;
    uint32_t b = 0x12345678;
    uint64_t c = 0x123456789abcdef0;

    std::cout << std::hex << bswap16(a) << "\n";
    std::cout << std::hex << bswap32(b) << "\n";
    std::cout << std::hex << bswap64(c) << "\n";

    return 0;
}

打印

3412
78563412
f0debc9a78563412
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

__builtin_xxx指令学习【5】__builtin_bswap16/32/64 的相关文章

随机推荐

  • 硬件结构——(6) 软中断

    1 中断是什么 xff1f 在计算机中 xff0c 中断是 系统用来响应硬件设备请求 的一种机制 操作系统收到 硬件的中断请求后 xff0c 会打断正在执行的进程 xff0c 然后调用内核中的 中断处理程序 来响应请求 中断是 种 异步的事
  • C++将类序列化和反序列化到共享内存

    这里用模板泛化一下 template lt typename T gt int saveToShm const T amp obj key t key 61 gen shm key int shmId 61 shmget key sizeo
  • C++使用rapidjson进行类的序列化与反序列化

    目录 序列化 amp 反序列化单个对象序列化反序列化使用示例 序列化 amp 反序列化对象列表 C 43 43 中可以使用第三方库来实现将类序列化成JSON文件 xff0c 以及读取JSON文件内容反序列化为类对象 这里使用rapidJso
  • c++用vector实现定长队列

    目录 queue实现vector实现 我们可以用queue或vector实现定长队列 xff0c 但是如果我们有遍历定长队列的需求的话 xff0c 使用queue不是一个好的选择 xff0c 因为queue本身不支持直接访问元素 queue
  • c++判断文件是否存在

    可以使用C 43 43 的文件流来判断文件是否存在 以下是一个简单的函数 xff0c 可以通过文件名判断文件是否存在 xff1a span class token macro property span class token direct
  • 相机内外参数的意义

    1 内参数 xff1a 由于相机坐标系使用的是毫米制的单位 xff0c 而图像平面使用的像素为单位 内参数的作用就是在这两个坐标系之间进行线性的变化 相机光轴中心Z轴方向与像平面交点称为投影中心 xff0c 其坐标为 xff0c 其单位为像
  • C++实现读写分离的双缓冲buffer

    目录 1 双缓冲区 读写分离2 后台线程定时更新数据3 类设计完整代码cache cppcache hmain cppmakefile 读写分离的双缓冲buffer有以下好处 xff1a 提高了并发读写的效率 xff1a 在多线程环境下 x
  • 返回引用与返回值与返回std::move(obj)

    返回引用与返回值相比 返回引用与返回值相比有以下几个好处 xff1a 减少内存开销 xff1a 返回值需要在函数内部创建一个临时对象 xff0c 然后将该对象的副本返回给调用者 这个过程需要分配内存 复制数据等操作 xff0c 会增加内存开
  • error: non-member function ‘XXX::IsValid(const T&)’ cannot have cv-qualifier

    这个错误提示表明你定义的函数 IsValid 是一个非成员函数 xff0c 并且带有 const 限定符 在 C 43 43 中 xff0c 非成员函数不能带有 const 限定符 xff0c 因为它们没有隐式的 this 指针 xff0c
  • c++使用regex报错regex_error

    原本写了个同时识别IPv4和IPv6地址的C 43 43 函数 xff1a span class token macro property span class token directive hash span span class to
  • c++实现日志类(写入logfile)

    span class token macro property span class token directive hash span span class token directive keyword include span spa
  • c++中以类对象作为key用于unordered_map、map,以及std::tie技巧使用

    我有一个类 span class token keyword class span span class token class name UserRegion span span class token punctuation span
  • std::set_difference用法

    std set difference 是 C 43 43 STL 中的一个算法 xff0c 用于计算两个有序范围之间的差集 xff0c 并将结果存储到另一个有序范围中 std set difference 的函数签名如下 xff1a spa
  • __builtin_xxx指令学习【1】__builtin_expect

    builtin expect是GCC编译器提供的一个内置函数 xff0c 用于告诉编译器一个分支的执行概率 xff0c 以便编译器在生成机器码时进行优化 它的语法如下 xff1a span class token function buil
  • __builtin_xxx指令学习【2】__builtin_prefetch

    builtin prefetch是GCC编译器提供的一个内置函数 xff0c 用于预取数据到CPU的缓存中 xff0c 以便提高程序的执行效率 它的语法如下 xff1a builtin prefetch const void addr in
  • __builtin_xxx指令学习【3】__builtin_popcount & __builtin_popcountll

    builtin popcount是GCC和Clang编译器提供的一个内置函数 xff0c 用于计算一个整数中二进制位为1的个数 该函数的使用背景是在一些位运算和计算机视觉等领域中 xff0c 需要对二进制数据进行处理和分析 xff0c 而二
  • 当arduino遇到树莓派(usb串口)

    arduino与树莓派cm4通过usb串口连接 xff1a 问题描述 前两天尝试了很久arduino和树莓派连接 终于找到了连接的方法 xff01 可恶 这是在简书找到的过程 主要是先在树莓派端导serial包 pip install se
  • Linux的rc.local自启动服务

    Linux的rc local自启动服务 网址 xff1a http blog csdn net 21aspnet article details 6826659 Linux有自己一套完整的启动体系 xff0c 抓住了linux启动的脉络 x
  • __builtin_xxx指令学习【4】__builtin_clz&__builtin_ctz & __builtin_clzll & __builtin_ctzll

    builtin clz是GCC和Clang编译器提供的一个内置函数 xff0c 用于计算一个整数的二进制表示中 xff0c 从最高位开始连续的0的个数 该函数的使用背景是在一些位运算和计算机视觉等领域中 xff0c 需要对二进制数据进行处理
  • __builtin_xxx指令学习【5】__builtin_bswap16/32/64

    builtin bswap16 32 64是GCC和Clang编译器提供的内置函数 xff0c 用于交换一个整数的字节顺序 其中 xff0c builtin bswap16用于交换一个16位整数的字节顺序 xff0c builtin bsw