x264 arm64汇编分析 quant8x8_neon分析

2024-04-02 16:04

本文主要是介绍x264 arm64汇编分析 quant8x8_neon分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一 C语言实现

#define QUANT_ONE( coef, mf, f ) \

{ \

    if( (coef) > 0 ) \

        (coef) = (f + (coef)) * (mf) >> 16; \

    else \

        (coef) = - ((f - (coef)) * (mf) >> 16); \

    nz |= (coef); \

}

static int quant_8x8( dctcoef dct[64], udctcoef mf[64], udctcoef bias[64] )

{

    int nz = 0;

    for( int i = 0; i < 64; i++ )

        QUANT_ONE( dct[i], mf[i], bias[i] );

    return !!nz;

}

二 汇编实现

//quant_8x8(int16_t dct[64], uint16_t mf[64], uint16_t bias[64])

function quant_8x8_neon, export=1

     ld1 {v16.8h, v17.8h}, [x0] //从地址x0加载数据到neon寄存器v16和v17

     abs v18.8h, v16.8h //对v16中的数据进行绝对值操作,并将结果存储在v18中

     abs v19.8h, v17.8h //对v17中的数据进行绝对值操作,并将结果存储在v19中

     ld1 {v0.8h, v1.8h}, [x2], #32 //从地址x2加载数据到neon寄存v0和v1,并跳过

     ld1 {v2.8h, v3.8h}, [x1], #32 //从地址x1加载数据到neon寄存器v2和v3,并跳过

     QUANT_TWO v0.8h, v1.8h, v2, v3, v4.16b//调用自定义的QUANT_TWO函数进行量化处理

.rept 3

//重复以下操作3次

    ld1 {v16.8h, v17.8h}, [x0] //v16, v17 dct系数

    abs v18.8h, v16.8h //求绝对值

    abs v19.8h, v17.8h //求绝对值

    ld1 {v0.8h, v1.8h}, [x2], #32

    ld1 {v2.8h, v3.8h}, [x1], #32

    QUANT_TWO v0.8h, v1.8h, v2, v3, v5.16b//再次强调QUANT_TWO函数进行量化处理

//v0.8h, v1.8h 存储偏移 数据64bits

//v2.8h,v3.8h 存储mf 量化因子64bits

    orr v4.16b, v4.16b, v5.16b //将每次量化处理的结果进行或操作,并存储在x4中

.endr

    uqxtn  v0.8b, v4.8h //对v4进行位转换操作

    QUANT_END d0 //量化处理结束

endfunc

// QUANT_TWO   v0.8h,  v1.8h,  v2,  v3,  v4.16b

//QUANT_TWO   v0.8h,  v1.8h,  v2,  v3,  v5.16b

// v0 v1存储偏移数组, v2,v3 量化因子mask用来输出结果

.macro QUANT_TWO bias0 bias1 mf0_1 mf2_3 mask

   add v18.8h, v18.8h, bias0 //绝对值v18.8h 相加bias0

   add v19.8h, v19.8h, bias1 //绝对值v19.8h 相加bias1

   umull v20.4s, v18.4h, mf0_1().4h //这里的h表示 harfword, 4half word量化因子4存入 v20.4s s表示s word, 32bits ,这个也是一致

   umull2 v21.4s, v18.8h, mf0_1().8h //这里h表示harfword, 4half word, 量化因子4存入v21.4s ,v18.8h 64位4个系数 和这个乘以mf量化因子4halfword

//意思乘以之后存入v21.4s

   umull v22.4s, v19.4h, mf2_3().4h

/*mf2_3().4h 的含义是4个half word,  乘以 v19.4h 存入 v22.4s */

   umull2 v23.4s, v19.8h, mf2_3().8h

/*高4个halfword 和 系数相乘 存入 v23.4s 4个sword 32bits的数据中*/

   sshr v16.8h, v16.8h, #15

/*v16以8个16bits 为单位,向右移位15位*/

   sshr v17.8h, v17.8h, #15

/*v17也是这样操作,看起来是取符号位, 取的低64bits*/

   shrn v18.4h, v20.4s, #16

/*对寄存器 v20 进行右移操作,移动 16 位,结果的低 16 位存储在寄存器 v18 中。*/

   shrn2 v18.8h, v21.4s, #16

//上面两句话,一句话写了v18的低64bits,一句话写了高64bits,组合成一个完整的v18寄存器的值

/*对寄存器 v21 进行右移操作,移动 16 位,结果的低 16 位存储在寄存器 v18 中。*/

   shrn v19.4h, v22.4s, #16

/*对寄存器 v22 进行右移操作,移动 16 位,结果的低 16 位存储在寄存器 v19 中。*/

   shrn2 v19.8h, v23.4s, #16

/*对寄存器 v23 进行右移操作,移动 16 位,结果的低 16 位存储在寄存器 v19 中。*/

   eor v18.16b, v18.16b, v16.16b

/*对寄存器 v18 v16 进行异或操作,结果存储在寄存器 v18字节 */

   eor v19.16b, v19.16b, v17.16b

/*对寄存器 v19 v17 进行异或操作,结果存储在寄存器 v19 字节中*/

   sub v18.8h, v19.8h, v16.8h

/*v16.8h 和 v19.8h 寄存器,相减 存入 18.8h */

   sub 19.8h, v19.8h, v17.8h

/*v7.8h 和 v19.8h 寄存器,相减 存入 19.8h*/

   orr mask, v18.16b, v19.16b

/*对寄存器 v18 v19 进行或操作,结果存储在寄存器 mask */

   st1 {v18.8h, v19.8h}, [x0], #32

/*把最终的结果存入,x0的内存位置,dct 数组*/

.endm

这篇关于x264 arm64汇编分析 quant8x8_neon分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/870425

相关文章

Python中的Walrus运算符分析示例详解

《Python中的Walrus运算符分析示例详解》Python中的Walrus运算符(:=)是Python3.8引入的一个新特性,允许在表达式中同时赋值和返回值,它的核心作用是减少重复计算,提升代码简... 目录1. 在循环中避免重复计算2. 在条件判断中同时赋值变量3. 在列表推导式或字典推导式中简化逻辑

Java程序进程起来了但是不打印日志的原因分析

《Java程序进程起来了但是不打印日志的原因分析》:本文主要介绍Java程序进程起来了但是不打印日志的原因分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java程序进程起来了但是不打印日志的原因1、日志配置问题2、日志文件权限问题3、日志文件路径问题4、程序

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

Python 迭代器和生成器概念及场景分析

《Python迭代器和生成器概念及场景分析》yield是Python中实现惰性计算和协程的核心工具,结合send()、throw()、close()等方法,能够构建高效、灵活的数据流和控制流模型,这... 目录迭代器的介绍自定义迭代器省略的迭代器生产器的介绍yield的普通用法yield的高级用法yidle

C++ Sort函数使用场景分析

《C++Sort函数使用场景分析》sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使... 目录C++ Sort函数详解一、sort函数调用的两种方式二、sort函数使用场景三、sort函数排序

kotlin中const 和val的区别及使用场景分析

《kotlin中const和val的区别及使用场景分析》在Kotlin中,const和val都是用来声明常量的,但它们的使用场景和功能有所不同,下面给大家介绍kotlin中const和val的区别,... 目录kotlin中const 和val的区别1. val:2. const:二 代码示例1 Java

Go标准库常见错误分析和解决办法

《Go标准库常见错误分析和解决办法》Go语言的标准库为开发者提供了丰富且高效的工具,涵盖了从网络编程到文件操作等各个方面,然而,标准库虽好,使用不当却可能适得其反,正所谓工欲善其事,必先利其器,本文将... 目录1. 使用了错误的time.Duration2. time.After导致的内存泄漏3. jsO

Spring事务中@Transactional注解不生效的原因分析与解决

《Spring事务中@Transactional注解不生效的原因分析与解决》在Spring框架中,@Transactional注解是管理数据库事务的核心方式,本文将深入分析事务自调用的底层原理,解释为... 目录1. 引言2. 事务自调用问题重现2.1 示例代码2.2 问题现象3. 为什么事务自调用会失效3

找不到Anaconda prompt终端的原因分析及解决方案

《找不到Anacondaprompt终端的原因分析及解决方案》因为anaconda还没有初始化,在安装anaconda的过程中,有一行是否要添加anaconda到菜单目录中,由于没有勾选,导致没有菜... 目录问题原因问http://www.chinasem.cn题解决安装了 Anaconda 却找不到 An

Spring定时任务只执行一次的原因分析与解决方案

《Spring定时任务只执行一次的原因分析与解决方案》在使用Spring的@Scheduled定时任务时,你是否遇到过任务只执行一次,后续不再触发的情况?这种情况可能由多种原因导致,如未启用调度、线程... 目录1. 问题背景2. Spring定时任务的基本用法3. 为什么定时任务只执行一次?3.1 未启用