浮点指令

  • 润物细无声
  • 2024-04-13 11:06

    intrinsic 指令

    由于浮点指令使用特殊寄存器(即浮点寄存器),所以在使用浮点指令时,操作数会加载到浮点寄存器中,操作完成之后再从寄存器拷贝出来。而且一些指令支持向量并行操作,所以手动汇编相对比较困难,而如果需要指定使用,则可以使用编译器提供的内联函数。这里主要记录 x86 的浮点内联函数,arm 也有浮点内联函数

    intel ICC 编译器和 gcc 编译支持 MME/SSE/AVX 的 C 接口,且两者命名基本相同( gcc 主要通过头文件对一些 __builtin_xxxx 的封装),关于支持了一些浮点内联函数,头文件,操作细节,版本,可见 intel 官网查询

    下面是这类函数大概的格式

    intrinsic-style

    1. 指令版本:_mm 开头为 sse 指令,_mm256AVX 指令
    2. 指令:cvtss 为操作指令,这里是转化 ss 为标量单精度,实际有这样的汇编指令(ps 为向量单精度,ss 为标量单精度,pd 为向量双精度,sd 为标量双精度,等)
    3. 数据类型:si32 为标量 32 位有符号整形

    寄存器分为标量与矢量

    vfp-register

    寄存器类型命名

    命名 含义
    __m128 包含 4 个 float 向量
    __m128d 包含 2 个 double 向量
    __m128i 包含若干个整形数字向量
    __m256 包含 8 个 float 向量
    __m256d 包含 4 个 double 向量
    __m256i 包含若干个整形数字向量

    数据类型定义

    类型 含义
    s Scalar 变量指令
    p Packed 包裹指令
    s 32 位 float
    d 64 位 double
    i32 带符号 32 位整形
    i64 带符号 64 位整形
    u32 无符号 32 位整形
    pixx xx 为长度,packed 操作所有的 xx 位有符号整形,使用寄存器长度为 64 位
    epixx xx 为长度,packed 操作所有的 xx 位有符号整数,使用寄存器长度为 128 位
    epuxx xx 为长度,packed 操作所有的 xx 位无符号整数
    ss 第一个单精度
    sd 第一个双精度
    ps 向量中所有的单精度
    pd 向量中所有的双精度

    使用举例

    double a = 3.0f;
    double b = 4.0f;
    double c = 0.0f;
    
    // 首先将 a b 加载到寄存器中
    __m128d n = _mm_set_sd(a);
    __m128d m = _mm_set_sd(b);
    
    // 执行标量除法(即浮点寄存器第一个双精度数据参与除法运算)
    n = _mm_sub_sd(n, m);
    
    // 在从寄存器取出转化到 double 类型内存变量中
    c = _mm_cvtsd_f64(n);
    

    再看 intel 对 _mm_sub_sd 函数介绍

    _mm_sub_sd

    包含了函数原型,头文件,对应指令用法,CPUID 检测标志,描述,操作过程(这对于指令模拟比较重要),以及在各个架构中的性能。下面是一些头文件和对应指令版本,仅参考:

    #include <mmintrin.h>           // mmx
    #include <xmmintrin.h>          // sse
    #include <emmintrin.h>          // sse2
    #include <pmmintrin.h>          // sse3
    #include <tmmintrin.h>          // sse3
    #include <intrin.h>             // 不关心哪个版本
    

    ARM 浮点指令简单介绍

    arm 浮点指令除了 VFP 还有 NEON。NEON 支持整数、定点和单精度浮点 SIMD 运算。是针对高级媒体和信号处理应用程序以及嵌入式处理器的 64/128 位混合 SIMD 技术。 它是作为 ARM 内核的一部分实现的,但有自己的执行管道和寄存器组,该寄存器组不同于 ARM 核心寄存器组。

    VFP 指令用 FADD,NEON 指令用 VADD。

    NEON 指令集比 VFP 指令集更广泛,因此,尽管大多数 VFP 指令具有等效的 NEON 指令,但仍有许多 NEON 指令执行 VFP 指令无法执行的操作。

    ARMv5 开始引入了 VFP (Vector Floating Point) 指令,该指令用于向量化加速浮点运算。自 ARMv7 开始正式引入 NEON 指令,NEON 性能远超 VFP,因此 VFP 指令被废弃。类似于 Intel CPU 下的 MMX/SSE/AVX/FMA 指令。

    © 2022-2024 留校察看 liuxocakn 保留所有权利 All Rights Reserved
    蜀ICP证2022022862号-1 川公网安备51010702003077号

    自 2024-04-23 22:54 之后访问量: 66476