CN110038301B - 数据处理方法、装置、电子设备及存储介质 - Google Patents

数据处理方法、装置、电子设备及存储介质 Download PDF

Info

Publication number
CN110038301B
CN110038301B CN201910290213.5A CN201910290213A CN110038301B CN 110038301 B CN110038301 B CN 110038301B CN 201910290213 A CN201910290213 A CN 201910290213A CN 110038301 B CN110038301 B CN 110038301B
Authority
CN
China
Prior art keywords
sse
function
data
instruction function
mathutil
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Active
Application number
CN201910290213.5A
Other languages
English (en)
Other versions
CN110038301A (zh
Inventor
冯艺
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Netease Hangzhou Network Co Ltd
Original Assignee
Netease Hangzhou Network Co Ltd
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Netease Hangzhou Network Co Ltd filed Critical Netease Hangzhou Network Co Ltd
Priority to CN201910290213.5A priority Critical patent/CN110038301B/zh
Publication of CN110038301A publication Critical patent/CN110038301A/zh
Application granted granted Critical
Publication of CN110038301B publication Critical patent/CN110038301B/zh
Active legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Images

Classifications

    • AHUMAN NECESSITIES
    • A63SPORTS; GAMES; AMUSEMENTS
    • A63FCARD, BOARD, OR ROULETTE GAMES; INDOOR GAMES USING SMALL MOVING PLAYING BODIES; VIDEO GAMES; GAMES NOT OTHERWISE PROVIDED FOR
    • A63F13/00Video games, i.e. games using an electronically generated display having two or more dimensions
    • A63F13/60Generating or modifying game content before or while executing the game program, e.g. authoring tools specially adapted for game development or game-integrated level editor

Landscapes

  • Engineering & Computer Science (AREA)
  • Multimedia (AREA)
  • Devices For Executing Special Programs (AREA)

Abstract

本申请提供了一种数据处理方法、装置、电子设备及存储介质。其中方法包括:调用SSE指令函数,将用于保存原始数据的第一内存地址和用于保存运算结果的第二内存地址传入所述SSE指令函数的参数;利用所述SSE指令函数调用非对齐内存读取接口函数从所述第一内存地址中读取所述原始数据,并将所述原始数据加载到SSE寄存器中;利用所述SSE指令函数调用逻辑运算函数对所述原始数据进行逻辑运算,并将运算结果保存至所述SSE寄存器中;利用所述SSE指令函数调用非对齐内存写入接口函数将所述运算结果写入所述第二内存地址。本申请能够保证数学库的SSE指令函数在普通的x86机器上正确运行,提高数学库整体的运算效率。

Description

数据处理方法、装置、电子设备及存储介质
技术领域
本申请涉及互联网技术领域,特别是涉及一种数据处理方法、装置、电子设备及存储介质。
背景技术
网络游戏简称“网游”,又称“在线游戏”。是指以互联网为传输媒介,以游戏运营商服务器和用户计算机为处理终端,以游戏客户端为信息交互窗口的旨在实现娱乐、休闲、交流和取得虚拟成就的具有可持续性的个体性多人在线游戏。
在游戏客户端中,涉及到大量的矩阵和向量运算,因此在游戏引擎引用的数学库中,通常会使用SIMD(Single Instruction Multiple Data,单指令多数据流)技术进行优化,以大幅提高运算速度。如ARM架构下的Neon指令,x86架构下的SSE(Streaming SIMDExtensions,单指令多数据流扩展)指令等。
在游戏引擎引用的数学库中,虽然包含SSE指令版本的函数实现,但是在实际测试中,这些代码并不能在普通的x86机器下正常运行。原因是SSE指令在读写内存时,要求内存地址以16字节对齐,否则会引起错误。目前数学库实现SSE指令的方式是使用C++的union(联合)数据结构,把向量/矩阵的数据与__m128数据类型“合并”在一起,共享同一块内存,并直接使用__m128成员变量进行SSE指令版本的函数的参数传递。但是,上述方式并没有保证__m128数据类型的内存地址以16字节对齐。因此在实际运行中,代码运行之后会触发程序崩溃,导致这些代码只能运行在特定的机器上,局限性较大。
发明内容
鉴于上述问题,提出了本申请以便提供克服上述问题或者至少部分地解决上述问题的一种数据处理方法、装置、电子设备及存储介质。
第一方面,本申请实施例提供了一种数据处理方法,所述方法包括:
调用SSE指令函数,将用于保存原始数据的第一内存地址和用于保存运算结果的第二内存地址传入所述SSE指令函数的参数;
利用所述SSE指令函数调用非对齐内存读取接口函数从所述第一内存地址中读取所述原始数据,并将所述原始数据加载到SSE寄存器中;
利用所述SSE指令函数调用逻辑运算函数对所述原始数据进行逻辑运算,并将运算结果保存至所述SSE寄存器中;
利用所述SSE指令函数调用非对齐内存写入接口函数将所述运算结果写入所述第二内存地址。
可选地,所述将所述原始数据加载到SSE寄存器中的步骤,包括:在所述原始数据为单精度浮点类型的矩阵数据时,将所述矩阵数据中的每一列数据加载到一个SSE寄存器中;在所述原始数据为单精度浮点类型的向量数据时,将所述向量数据加载到一个SSE寄存器中。
可选地,所述调用SSE指令函数,将用于保存原始数据的第一内存地址及用于保存运算结果的第二内存地址传入所述SSE指令函数的参数的步骤,包括:利用Mat4类中定义的Mat4指令函数通过统一MathUtil函数接口调用MathUtil类中定义的MathUtil指令函数,将所述第一地址和所述第二地址传入所述MathUtil指令函数的参数;利用所述MathUtil指令函数通过第一SSE函数接口调用MathUtilSSE类中定义的所述SSE指令函数,将所述第一地址和所述第二地址传入所述SSE指令函数的参数。
可选地,所述方法还包括:删除MathUtil.h头文件中定义的第二SSE函数接口;所述第二SSE函数接口的参数为__m128类型传递;在所述MathUtilSSE类中定义所述第一SSE函数接口;所述第一SSE函数接口的参数为内存地址传递。
可选地,所述方法还包括:在所述MathUtil指令函数中添加调用所述SSE指令函数的SSE实现语句;所述利用所述MathUtil指令函数通过第一SSE函数接口调用MathUtilSSE类中定义的SSE指令函数的步骤,包括:利用所述MathUtil指令函数执行所述SSE实现语句,通过第一SSE函数接口调用MathUtilSSE类中定义的SSE指令函数。
可选地,所述方法还包括:将用于声明数据结构与成员函数的头文件中,xmmintrin.h头文件修改为mmintrin.h头文件,并删除union数据结构封装;将MathUtil.h头文件中,xmmintrin.h头文件修改为mmintrin.h头文件;在所述mmintrin.h头文件中定义有所述非对齐内存读取接口函数、所述逻辑运算函数和所述非对齐内存写入接口函数。
第二方面,本申请实施例提供了一种数据处理装置,所述装置包括:
调用模块,用于调用SSE指令函数,将用于保存原始数据的第一内存地址和用于保存运算结果的第二内存地址传入所述SSE指令函数的参数;
读取加载模块,用于利用所述SSE指令函数调用非对齐内存读取接口函数从所述第一内存地址中读取所述原始数据,并将所述原始数据加载到SSE寄存器中;
运算模块,用于利用所述SSE指令函数调用逻辑运算函数对所述原始数据进行逻辑运算,并将运算结果保存至所述SSE寄存器中;
写入模块,用于利用所述SSE指令函数调用非对齐内存写入接口函数将所述运算结果写入所述第二内存地址。
可选地,所述读取加载模块包括:矩阵加载单元,用于在所述原始数据为单精度浮点类型的矩阵数据时,将所述矩阵数据中的每一列数据加载到一个SSE寄存器中;向量加载单元,用于在所述原始数据为单精度浮点类型的向量数据时,将所述向量数据加载到一个SSE寄存器中。
可选地,所述调用模块包括:第一调用单元,用于利用Mat4类中定义的Mat4指令函数通过统一MathUtil函数接口调用MathUtil类中定义的MathUtil指令函数,将所述第一地址和所述第二地址传入所述MathUtil指令函数的参数;第二调用单元,用于利用所述MathUtil指令函数通过第一SSE函数接口调用MathUtilSSE类中定义的所述SSE指令函数,将所述第一地址和所述第二地址传入所述SSE指令函数的参数。
可选地,所述装置还包括:删除模块,用于删除MathUtil.h头文件中定义的第二SSE函数接口;所述第二SSE函数接口的参数为__m128类型传递;定义模块,用于在所述MathUtilSSE类中定义所述第一SSE函数接口;所述第一SSE函数接口的参数为内存地址传递。
可选地,所述装置还包括:添加模块,用于在所述MathUtil指令函数中添加调用所述SSE指令函数的SSE实现语句;所述第二调用单元,用于利用所述MathUtil指令函数执行所述SSE实现语句,通过第一SSE函数接口调用MathUtilSSE类中定义的SSE指令函数,将所述第一地址和所述第二地址传入所述SSE指令函数的参数。
可选地,所述装置还包括:第一修改模块,用于将用于声明数据结构与成员函数的头文件中,xmmintrin.h头文件修改为mmintrin.h头文件,并删除union数据结构封装;第二修改模块,用于将MathUtil.h头文件中,xmmintrin.h头文件修改为mmintrin.h头文件;在所述mmintrin.h头文件中定义有所述非对齐内存读取接口函数、所述逻辑运算函数和所述非对齐内存写入接口函数。
第三方面,本申请实施例提供了一种电子设备,包括:处理器;用于存储处理器可执行指令的存储器;其中,所述处理器被配置为执行如上任一项所述的数据处理方法。
第四方面,本申请实施例提供了一种非临时性计算机可读存储介质,当所述存储介质中的指令由电子设备的处理器执行时,使得电子设备能够执行如上任一项所述的数据处理方法。
在本申请实施例中,在对原始数据进行逻辑运算时,调用SSE指令函数,将用于保存原始数据的第一内存地址和用于保存运算结果的第二内存地址传入所述SSE指令函数的参数;利用所述SSE指令函数调用非对齐内存读取接口函数从所述第一内存地址中读取所述原始数据,并将所述原始数据加载到SSE寄存器中;利用所述SSE指令函数调用逻辑运算函数对所述原始数据进行逻辑运算,并将运算结果保存至所述SSE寄存器中;利用所述SSE指令函数调用非对齐内存写入接口函数将所述运算结果写入所述第二内存地址。
由此可知,本申请实施例中取消了游戏引擎自带的union封装方式,参数传递时候,不使用__m128数据类型,而是传递原始数据的内存地址,并在SSE版本的函数体内,使用非对齐内存读取接口函数和非对齐内存写入接口函数进行内存的读写,在运算开始前将原始数据从内存从读到SSE寄存器,在数学运算结束后将SSE寄存器内的运算结果写入内存中。因此,能够保证数学库的SSE指令函数在普通的x86机器上正确运行,提高数学库整体的运算效率。
附图说明
为了更清楚地说明本申请的技术方案,下面将对本申请的描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本申请的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动性的前提下,还可以根据这些附图获得其他的附图。
图1是本申请实施例的一种数据处理方法的步骤流程图;
图2是本申请实施例的另一种数据处理方法的步骤流程图;
图3是申请实施例的一种将Mat4.h中xmmintrin.h头文件修改为mmintrin.h头文件的代码示意图;
图4是申请实施例的一种将Mat4.h中union的数据结构封装删除之前的代码示意图;
图5是申请实施例的一种将Mat4.h中union的数据结构封装删除之后的代码示意图;
图6是申请实施例的一种将Vec4.h中xmmintrin.h头文件修改为mmintrin.h头文件的代码示意图;
图7是申请实施例的一种将Vec4.h中union的数据结构封装删除之前的代码示意图;
图8是申请实施例的一种将Vec4.h中union的数据结构封装删除之后的代码示意图;
图9是申请实施例的一种对MathUtil.h进行修改的代码示意图;
图10是申请实施例的一种在MathUtil::addMatrix中添加调用SSE指令函数的SSE实现语句的代码示意图;
图11是申请实施例的一种在Mat4::add中删除SSE版本的MathUtil函数调用语句的代码示意图;
图12是申请实施例的一种在MathUtilSSE类中定义第一SSE函数接口的代码示意图;
图13是现有技术的一种MathUtilSSE::addMatrix实现的代码示意图;
图14是本申请实施例的一种MathUtilSSE::addMatrix实现的代码示意图;
图15是现有技术的另一种MathUtilSSE::addMatrix实现的代码示意图;
图16是本申请实施例的另一种MathUtilSSE::addMatrix实现的代码示意图;
图17是现有技术的一种MathUtilSSE::subtractMatrix实现的代码示意图;
图18是本申请实施例的一种MathUtilSSE::subtractMatrix实现的代码示意图;
图19是现有技术的一种MathUtilSSE::multiplyMatrix实现的代码示意图;
图20是本申请实施例的一种MathUtilSSE::multiplyMatrix实现的代码示意图;
图21是现有技术的一种MathUtilSSE::multiplyMatrix实现的代码示意图;
图22是本申请实施例的一种MathUtilSSE::multiplyMatrix实现的代码示意图;
图23是现有技术的一种MathUtilSSE::negateMatrix实现的代码示意图;
图24是本申请实施例的一种MathUtilSSE::negateMatrix实现的代码示意图;
图25是现有技术的一种MathUtilSSE::transposeMatrix实现的代码示意图;
图26是本申请实施例的一种MathUtilSSE::transposeMatrix实现的代码示意图;
图27是现有技术的一种MathUtilSSE::transformVec4实现的代码示意图;
图28是本申请实施例的一种MathUtilSSE::transformVec4实现的代码示意图;
图29是本申请实施例的一种开启SSE指令优化的示意图;
图30是现有技术中数学库逻辑运算函数的CPU占用时间示意图;
图31是本申请实施例中数学库逻辑运算函数的CPU占用时间示意图;
图32是本申请实施例的一种数据处理装置的结构框图。
具体实施方式
下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都属于本申请保护的范围。
参照图1,示出了本申请实施例的一种数据处理方法的步骤流程图。
本申请实施例的数据处理方法包括以下步骤:
步骤101,调用SSE指令函数,将用于保存原始数据的第一内存地址和用于保存运算结果的第二内存地址传入所述SSE指令函数的参数。
SSE是英特尔在AMD的3D Now!发布一年之后,在其计算机芯片Pentium III中引入的指令集,是MMX的超集。它包括70条指令,其中包含单指令多数据浮点计算、以及额外的SIMD整数和高速缓存控制指令。其优势包括:更高分辨率的图像浏览和处理、高质量音频、MPEG2(Moving Picture Experts Group,动态图像专家组)视频、同时MPEG2加解密;语音识别占用更少CPU(Central Processing Unit,中央处理单元)资源;更高精度和更快响应速度。在游戏引擎中,通常会使用SSE指令提高运算速度。本申请实施例的游戏引擎可以为Cocos2dx引擎,Cocos2dx是一个开源的移动2D游戏框架,游戏开发快速、简易、功能强大。
比如在一种应用场景下,游戏中有大量的实体,实体的位置经常发生变化,因为游戏引擎每一帧都要获得当前游戏实体的位置,才能正确地把游戏实体渲染到屏幕上。而游戏实体位置发生变化,要通过逻辑运算计算出正确的屏幕坐标,以便正确地渲染出来。在该种场景下,游戏引擎可以使用SSE指令函数进行逻辑运算。
本申请实施例中,在需要对原始数据进行逻辑运算时,获取用于保存原始数据的第一内存地址和用于保存运算结果的第二内存地址,调用SSE指令函数,将第一内存地址和第二内存地址传入SSE指令函数的参数。
原始数据是指要进行逻辑运算的数据。原始数据可以包括实体相关数据,也可以包括实体相关数据和转换相关数据。其中,实体相关数据是指游戏实体的数据,比如当前游戏实体的位置等;转换相关数据是指对实体相关数据进行转换所参考的数据,比如参考矩阵、参考常数等。
SSE指令函数可以包括矩阵相加的SSE指令函数、矩阵相减的SSE指令函数、矩阵相乘的SSE指令函数、求反矩阵的SSE指令函数、求转置矩阵的SSE指令函数、矩阵与向量相乘的SSE指令函数等。
比如,原始数据包括实体的位置向量和转换的参考矩阵,对实体的位置向量和转换的参考矩阵进行矩阵与向量相乘操作,则调用矩阵与向量相乘的SSE指令函数,将用于保存实体的位置向量的内存地址、用于保存转换的参考矩阵的内存地址和用于保存运算结果的内存地址传入矩阵与向量相乘的SSE指令函数的参数。
步骤102,利用所述SSE指令函数调用非对齐内存读取接口函数从所述第一内存地址中读取所述原始数据,并将所述原始数据加载到SSE寄存器中。
原始数据以单精度浮点类型保存在内存中,一个单精度浮点类型数据为32位。一个SSE寄存器为128位寄存器,因此一个SSE寄存器可以用来存放四个32位的单精确度浮点类型数据。
因此,将原始数据加载到SSE寄存器中的步骤可以包括:在所述原始数据为单精度浮点类型的矩阵数据(4×4的矩阵)时,将所述矩阵数据中的每一列数据加载到一个SSE寄存器中;在所述原始数据为单精度浮点类型的向量数据(1×4的向量)时,将所述向量数据加载到一个SSE寄存器中。加载到SSE寄存器,具体为将原始数据载入数据类型为__m128的变量中。
步骤103,利用所述SSE指令函数调用逻辑运算函数对所述原始数据进行逻辑运算,并将运算结果保存至所述SSE寄存器中。
利用SSE指令函数调用逻辑运算函数对加载到SSE寄存器中的原始数据进行逻辑运算,通常情况下将运算结果保存至用于加载实体相关数据的SSE寄存器中。
步骤104,利用所述SSE指令函数调用非对齐内存写入接口函数将所述运算结果写入所述第二内存地址。
本申请实施例中取消了游戏引擎自带的union封装方式,参数传递时候,不使用__m128数据类型,而是传递原始数据的内存地址,并在SSE版本的函数体内,使用非对齐内存读取接口函数和非对齐内存写入接口函数进行内存的读写,在运算开始前将原始数据从内存从读到SSE寄存器,在数学运算结束后将SSE寄存器内的运算结果写入内存中。因此,能够保证数学库的SSE指令函数在普通的x86机器上正确运行,提高数学库整体的运算效率。
参照图2,示出了本申请实施例的另一种数据处理方法的步骤流程图。
本申请实施例的数据处理方法包括以下步骤:
步骤201,将用于声明数据结构与成员函数的头文件中,xmmintrin.h头文件修改为mmintrin.h头文件,并删除union数据结构封装。
xmmintrin.h头文件里包含MMX头文件。由于本申请实施例中所调用的一些SSE指令函数在mmintrin.h中定义,比如非对齐内存读取接口函数、逻辑运算函数、非对齐内存写入接口函数等都在mmintrin.h中定义,因此将xmmintrin.h头文件修改为mmintrin.h头文件,以便后续正确调用这些函数。
用于声明数据结构与成员函数的头文件中包括union数据结构封装代码,而本申请实施例中不再使用union数据结构进行封装,因此可以删除union数据结构封装。
本申请实施例中,用于声明数据结构与成员函数的头文件可以包括Mat4.h头文件和Vec4.h头文件。Mat4.h是数学库中的一个头文件,用于声明4x4矩阵的数据结构及成员函数。Vec4.h是数学库中的一个头文件,用于声明1x4向量的数据结构与成员函数。
图3示出了申请实施例的一种将Mat4.h中xmmintrin.h头文件修改为mmintrin.h头文件的代码示意图。删除Mat4.h中的#include<xmintrin.h>代码,添加#include<mmintrin.h>代码。
图4示出了申请实施例的一种将Mat4.h中union的数据结构封装删除之前的代码示意图。图5示出了申请实施例的一种将Mat4.h中union的数据结构封装删除之后的代码示意图。将图4所示的代码中Mat4.h中的union数据结构封装代码(78行~83行)删掉,得到如图5所示的代码,直接使用float m[16]存储Mat4类型的数据(78行)。Mat4类型是用来描述4x4的矩阵,矩阵中每一个元素是一个浮点数。因此,m[16]就是用来存储这16个元素的数据结构,每个元素都是float类型(单精度浮点类型)。
图6示出了申请实施例的一种将Vec4.h中xmmintrin.h头文件修改为mmintrin.h头文件的代码示意图。删除Vec4.h中的#include<xmintrin.h>代码,添加#include<mmintrin.h>代码。
图7示出了申请实施例的一种将Vec4.h中union的数据结构封装删除之前的代码示意图。图8示出了申请实施例的一种将Vec4.h中union的数据结构封装删除之后的代码示意图。将图7所示的代码中Vec4.h中的union数据结构封装代码(46行~56行)删掉,得到如图8所示的代码,直接使用float x,y,z,w存储Vec4类型的数据(47行~66行)。Vec4类型是用来描述1x4的向量,1x4向量有4个分量,分别为x,y,z,w。
步骤202,将MathUtil.h头文件中,xmmintrin.h头文件修改为mmintrin.h头文件,并删除MathUtil.h头文件中定义的第二SSE函数接口。
MathUtil.h是数学库中的一个头文件,用于声明数学库对外部的抽象接口,以提供数学运算支持。将MathUtil.h头文件中的xmmintrin.h头文件修改为mmintrin.h头文件,以便后续正确调用mmintrin.h头文件中定义的函数。
MathUtil.h头文件中定义了第二SSE函数接口,第二SSE函数接口的参数为__m128类型传递,而本申请实施例中不再使用__m128类型传递,因此可以删除MathUtil.h头文件中定义的第二SSE函数接口。
图9示出了申请实施例的一种对MathUtil.h进行修改的代码示意图。如图9所示,删除MathUtil.h中的#include<xmintrin.h>代码,添加#include<mmintrin.h>代码,删除MathUtil.h中18行~34行定义的第二SSE函数接口代码。
步骤203,在MathUtil指令函数中添加调用SSE指令函数的SSE实现语句。
MathUtil.cpp是数学库中的一个模块,声明了数学库对外部的抽象接口,以及定义了接口的具体实现,以提供数学运算支持。修改MathUtil.cpp,在MathUtil指令函数中添加调用SSE指令函数的SSE实现语句,以便后续正确调用MathUtilSSE类中定义的SSE指令函数。
MathUtil指令函数可以包括MathUtil::addMatrix(矩阵相加的MathUtil指令函数)、MathUtil::subtractMatrix(矩阵相减的MathUtil指令函数)、MathUtil::multiplyMatrix(矩阵相乘的MathUtil指令函数)、MathUtil::negateMatrix(求反矩阵的MathUtil指令函数)、MathUtil::transposeMatrix(求转置矩阵的MathUtil指令函数)、MathUtil::transformVec4(矩阵与向量相乘的MathUtil指令函数)。
图10示出了申请实施例的一种在MathUtil::addMatrix中添加调用SSE指令函数的SSE实现语句的代码示意图。如图10所示,在原来的MathUtil::addMatrix函数里加上:
#elif defined(__SSE__)
MathUtilSSE:addMatrix(m,scalar,dst);
#else
表示若打开了SSE优化,则调用SSE版本对应的指令函数。
步骤204,在Mat4指令函数中删除SSE版本的MathUtil函数调用语句。
Mat4.cpp定义了4x4矩阵类型的相关接口实现。Mat4类的函数可以调用MathUtil类的函数,以实现函数功能。修改Mat4.cpp,在Mat4指令函数中删除SSE版本的MathUtil函数调用语句,使其不再调用步骤202中删除的第二SSE函数接口,改为调用统一MathUtil函数接口。
与上述MathUtil指令函数对应,Mat4指令函数可以包括Mat4::add(矩阵相加的Mat4指令函数)、Mat4::subtract(矩阵相减的Mat4指令函数)、Mat4::multiply(矩阵相乘的Mat4指令函数)、Mat4::negate(求反矩阵的Mat4指令函数)、Mat4::transpose(求转置矩阵的Mat4指令函数)、Mat4::transformVector(矩阵与向量相乘的Mat4指令函数)。
图11示出了申请实施例的一种在Mat4::add中删除SSE版本的MathUtil函数调用语句的代码示意图。如图11所示,删除9行~11行以及13行的代码,直接调用12行所示的统一MathUtil::addMatrix接口。
步骤205,在MathUtilSSE类中定义第一SSE函数接口。
MathUtilSSE.inl声明与定义了使用SSE指令优化时的具体实现。实现上,若开启了SSE优化,则MathUtil类的函数调用MathUtilSSE类对应的函数,若没有开启SSE优化,则MathUtil类的函数调用普通版本的实现函数。
修改MathUtilSSE.inl,新增class MathUtilSSE(MathUtilSSE类),在MathUtilSSE类中定义第一SSE函数接口,也即将步骤202中删除的第二SSE函数接口转移到MathUtilSSE类中定义,并且第一SSE函数接口的参数修改为内存地址传递。
图12示出了申请实施例的一种在MathUtilSSE类中定义第一SSE函数接口的代码示意图。图12中定义的第一SSE函数接口与图9中删除的第二SSE函数接口对应,包括7行~21行代码定义的8个第一SSE函数接口。
比如,原来在MathUtil.h头文件中定义的第二SSE函数接口为:
static void addMatrix(const__m128 m[4],float scalar,__m128 dst[4]);
该第二SSE函数接口的参数为__m128类型传递。
将其对应在MathUtilSSE类中定义的第一SSE函数接口为:
static void addMatrix(const float*m,float scalar,float*dst);
该第一SSE函数接口的参数为内存地址传递。
步骤206,修改MathUtilSSE类中定义的SSE指令函数的实现。
本申请实施例中,SSE指令函数在实现上,由原来的传递__m128类型的数据,修改为传递内存地址;由原来的直接获取__m128类型的数据,修改为使用非对齐内存读取接口函数将原始数据从内存从读到SSE寄存器;由原来的将运算结果直接返回内存,修改为将运算结果保存至SSE寄存器中,并使用非对齐内存写入接口函数将SSE寄存器内的运算结果写入内存中。
SSE指令函数可以包括MathUtilSSE::addMatrix(矩阵相加的SSE指令函数)、MathUtilSSE::subtractMatrix(矩阵相减的SSE指令函数)、MathUtilSSE::multiplyMatrix(矩阵相乘的SSE指令函数)、MathUtilSSE::negateMatrix(求反矩阵的SSE指令函数)、MathUtilSSE::transposeMatrix(求转置矩阵的SSE指令函数)、MathUtilSSE::transformVec4(矩阵与向量相乘的SSE指令函数)。其中MathUtilSSE::addMatrix包括矩阵与常数相加和矩阵与矩阵相加两种,MathUtilSSE::multiplyMatrix包括矩阵与常数相乘和矩阵与矩阵相乘两种。
图13示出了现有技术的一种MathUtilSSE::addMatrix实现的代码示意图。由图13可知,现有技术中直接获取m[0]~m[3]的数据进行_mm_add_ps的运算,并把_mm_add_ps的返回数据直接写入dst中。
图14示出了本申请实施例的一种MathUtilSSE::addMatrix实现的代码示意图。由图14可知,本申请实施例中通过_mm_loadu_ps(&m[0])读取出col1,相当于原来的m[0];通过_mm_loadu_ps(&m[4])读取出col2,相当于原来的m[1];通过_mm_loadu_ps(&m[8])读取出col3,相当于原来的m[2];通过_mm_loadu_ps(&m[12])读取出col4,相当于原来的m[3]。将读取的数据载入__m128类型数据,利用逻辑运算函数_mm_add_ps对读取的数据进行逻辑运算,使用_mm_storeu_ps接口将运算结果写入dst中。其中,_mm_loadu_ps为非对齐内存读取接口,_mm_storeu_ps为非对齐内存写入接口。
图13和图14中的MathUtilSSE::addMatrix具体为矩阵与常数相加的SSE指令函数。
图15示出了现有技术的另一种MathUtilSSE::addMatrix实现的代码示意图。由图15可知,现有技术中直接获取m1[0]~m1[3]及m2[0]~m2[3]的数据进行_mm_add_ps的运算,并把_mm_add_ps的返回数据直接写入dst中。
图16示出了本申请实施例的另一种MathUtilSSE::addMatrix实现的代码示意图。由图16可知,本申请实施例中通过_mm_loadu_ps(&m1[0])读取m1c1,相当于原来的m1[0];通过_mm_loadu_ps(&m1[4])读取出m1c2,相当于原来的m1[1];通过_mm_loadu_ps(&m1[8])读取出m1c3,相当于原来的m1[2];通过_mm_loadu_ps(&m1[12])读取出m1c4,相当于原来的m1[3];通过_mm_loadu_ps(&m2[0])读取m2c1,相当于原来的m2[0];通过_mm_loadu_ps(&m2[4])读取出m2c2,相当于原来的m2[1];通过_mm_loadu_ps(&m2[8])读取出m2c3,相当于原来的m2[2];通过_mm_loadu_ps(&m2[12])读取出m2c4,相当于原来的m2[3]。将读取的数据载入__m128类型数据,利用逻辑运算函数_mm_add_ps对读取的数据进行逻辑运算,使用_mm_storeu_ps接口将运算结果写入dst中。
图15和图16中的MathUtilSSE::addMatrix具体为矩阵与矩阵相加的SSE指令函数。
图17示出了现有技术的一种MathUtilSSE::subtractMatrix实现的代码示意图。由图17可知,现有技术中直接获取m1[0]~m1[3]及m2[0]~m2[3]的数据进行_mm_sub_ps的运算,并把_mm_sub_ps的返回数据直接写入dst中。
图18示出了本申请实施例的一种MathUtilSSE::subtractMatrix实现的代码示意图。由图18可知,本申请实施例中通过_mm_loadu_ps(&m1[0])读取m1c1,相当于原来的m1[0];通过_mm_loadu_ps(&m1[4])读取出m1c2,相当于原来的m1[1];通过_mm_loadu_ps(&m1[8])读取出m1c3,相当于原来的m1[2];通过_mm_loadu_ps(&m1[12])读取出m1c4,相当于原来的m1[3];通过_mm_loadu_ps(&m2[0])读取m2c1,相当于原来的m2[0];通过_mm_loadu_ps(&m2[4])读取出m2c2,相当于原来的m2[1];通过_mm_loadu_ps(&m2[8])读取出m2c3,相当于原来的m2[2];通过_mm_loadu_ps(&m2[12])读取出m2c4,相当于原来的m2[3]。将读取的数据载入__m128类型数据,利用逻辑运算函数_mm_sub_ps对读取的数据进行逻辑运算,使用_mm_storeu_ps接口将运算结果写入dst中。
图19示出了现有技术的一种MathUtilSSE::multiplyMatrix实现的代码示意图。由图19可知,现有技术中直接获取m[0]~m[3]的数据进行_mm_mul_ps的运算,并把_mm_mul_ps的返回数据直接写入dst中。
图20示出了本申请实施例的一种MathUtilSSE::multiplyMatrix实现的代码示意图。由图20可知,本申请实施例中通过_mm_loadu_ps(&m[0])读取出col1,相当于原来的m[0];通过_mm_loadu_ps(&m[4])读取出col2,相当于原来的m[1];通过_mm_loadu_ps(&m[8])读取出col3,相当于原来的m[2];通过_mm_loadu_ps(&m[12])读取出col4,相当于原来的m[3]。将读取的数据载入__m128类型数据,利用逻辑运算函数_mm_mul_ps对读取的数据进行逻辑运算,使用_mm_storeu_ps接口将运算结果写入dst中。
图19和图20中的MathUtilSSE::multiplyMatrix具体为矩阵与常数相乘的SSE指令函数。
图21示出了现有技术的一种MathUtilSSE::multiplyMatrix实现的代码示意图。由图21可知,现有技术中直接获取m1[0]~m1[3]及m2[0]~m2[3]的数据进行_mm_shuffle_ps、_mm_mul_ps、_mm_add_ps的运算,并把返回的结果数据直接写入dst中。
图22示出了本申请实施例的一种MathUtilSSE::multiplyMatrix实现的代码示意图。由图22可知,本申请实施例中通过_mm_loadu_ps(&m1[0])读取m1c1,相当于原来的m1[0];通过_mm_loadu_ps(&m1[4])读取出m1c2,相当于原来的m1[1];通过_mm_loadu_ps(&m1[8])读取出m1c3,相当于原来的m1[2];通过_mm_loadu_ps(&m1[12])读取出m1c4,相当于原来的m1[3];通过_mm_loadu_ps(&m2[0])读取m2c1,相当于原来的m2[0];通过_mm_loadu_ps(&m2[4])读取出m2c2,相当于原来的m2[1];通过_mm_loadu_ps(&m2[8])读取出m2c3,相当于原来的m2[2];通过_mm_loadu_ps(&m2[12])读取出m2c4,相当于原来的m2[3]。将读取的数据载入__m128类型数据,利用逻辑运算函数_mm_shuffle_ps、_mm_mul_ps、_mm_add_ps对读取的数据进行逻辑运算,使用_mm_storeu_ps接口将运算结果写入dst中。
图21和图22中的MathUtilSSE::multiplyMatrix具体为矩阵与矩阵相乘的SSE指令函数。
图23示出了现有技术的一种MathUtilSSE::negateMatrix实现的代码示意图。由图23可知,现有技术中直接获取m[0]~m[3]的数据进行_mm_sub_ps的运算,并把_mm_sub_ps的返回数据直接写入dst中。
图24示出了本申请实施例的一种MathUtilSSE::negateMatrix实现的代码示意图。由图24可知,本申请实施例中通过_mm_loadu_ps(&m[0])读取出col1,相当于原来的m[0];通过_mm_loadu_ps(&m[4])读取出col2,相当于原来的m[1];通过_mm_loadu_ps(&m[8])读取出col3,相当于原来的m[2];通过_mm_loadu_ps(&m[12])读取出col4,相当于原来的m[3]。将读取的数据载入__m128类型数据,利用逻辑运算函数_mm_sub_ps对读取的数据进行逻辑运算,使用_mm_storeu_ps接口将运算结果写入dst中。
图25示出了现有技术的一种MathUtilSSE::transposeMatrix实现的代码示意图。由图25可知,现有技术中直接获取m[0]~m[3]的数据进行_mm_shuffle_ps的运算,并把_mm_shuffle_ps的返回数据直接写入dst中。
图26示出了本申请实施例的一种MathUtilSSE::transposeMatrix实现的代码示意图。由图26可知,本申请实施例中通过_mm_loadu_ps(&m[0])读取出col1,相当于原来的m[0];通过_mm_loadu_ps(&m[4])读取出col2,相当于原来的m[1];通过_mm_loadu_ps(&m[8])读取出col3,相当于原来的m[2];通过_mm_loadu_ps(&m[12])读取出col4,相当于原来的m[3]。将读取的数据载入__m128类型数据,利用逻辑运算函数_mm_shuffle_ps对读取的数据进行逻辑运算,使用_mm_storeu_ps接口将运算结果写入dst中。
图27示出了现有技术的一种MathUtilSSE::transformVec4实现的代码示意图。由图27可知,现有技术中直接获取m[0]~m[3]的数据进行_mm_shuffle_ps、_mm_add_ps的运算,并把返回的结果数据直接写入dst中。
图28示出了本申请实施例的一种MathUtilSSE::transformVec4实现的代码示意图。由图28可知,本申请实施例中通过_mm_loadu_ps(v)读取出向量v,通过_mm_loadu_ps(&m[0])读取出mc1,相当于原来的m[0];通过_mm_loadu_ps(&m[4])读取出mc2,相当于原来的m[1];通过_mm_loadu_ps(&m[8])读取出mc3,相当于原来的m[2];通过_mm_loadu_ps(&m[12])读取出mc4,相当于原来的m[3]。将读取的数据载入__m128类型数据,利用逻辑运算函数_mm_shuffle_ps、_mm_add_ps对读取的数据进行逻辑运算,使用_mm_storeu_ps接口将运算结果写入dst中。
图29示出了本申请实施例的一种开启SSE指令优化的示意图。经过上述步骤201~步骤206对数学库进行修改后,如图29所示,在VisualStudio中选择libcocos2d工程,添加__SSE__预编译宏,开启SSE指令优化。
步骤207,利用Mat4类中定义的Mat4指令函数通过统一MathUtil函数接口调用MathUtil类中定义的MathUtil指令函数,将用于保存原始数据的第一内存地址和用于保存运算结果的第二内存地址传入MathUtil指令函数的参数。
当需要对原始数据进行逻辑运算时,即可使用上述修改后的数学库。获取用于保存原始数据的第一内存地址和用于保存运算结果的第二内存地址,利用步骤204中提到的Mat4类中定义的Mat4指令函数通过统一MathUtil函数接口调用步骤203中提到的MathUtil类中定义的MathUtil指令函数,将第一内存地址和第二内存地址传入MathUtil指令函数的参数。
步骤208,利用MathUtil指令函数通过第一SSE函数接口调用MathUtilSSE类中定义的SSE指令函数,将所述第一地址和所述第二地址传入所述SSE指令函数的参数。
利用步骤203中提到的MathUtil类中定义的MathUtil指令函数,执行步骤203中添加的调用SSE指令函数的SSE实现语句,通过步骤205中定义的第一SSE函数接口,调用步骤206中MathUtilSSE类中定义的SSE指令函数,将第一地址和第二地址传入SSE指令函数的参数。
步骤209,利用所述SSE指令函数调用非对齐内存读取接口函数从第一内存地址中读取所述原始数据,并将所述原始数据加载到SSE寄存器中。
步骤210,利用所述SSE指令函数调用逻辑运算函数对所述原始数据进行逻辑运算,并将运算结果保存至所述SSE寄存器中。
步骤211,利用所述SSE指令函数调用非对齐内存写入接口函数将所述运算结果写入所述第二内存地址。
将第一地址和第二地址传入SSE指令函数的参数后,SSE指令函数即可按照执行步骤206中修改后的SSE指令函数的实现代码。得到运算结果后,调用绘图接口,将第二内存地址中的运算结果渲染到屏幕上。
以下举例说明。游戏中的一个实体,其位置发生改变,若改变后相对父节点位置为(x,y,z),要将该实体正确渲染到屏幕上,则要将这个相对父节点位置进行世界矩阵及投影矩阵的变换。假设要对其位置进行变换处理的矩阵是M(4x4的矩阵),保存M的内存地址为m;实体的位置向量为V=(x,y,z,1),保存V的内存地址为v;最终的屏幕位置为Vs=M*V,保存Vs的内存地址为dst。其中,M和V为原始数据,M为转换相关数据,V为实体相关数据。这个相乘操作就会用到数学库中的矩阵和向量相乘的指令函数。
利用Mat4::transformVector函数通过统一MathUtil函数接口调用MathUtil::transformVec4函数,将m、v和dst传入MathUtil::transformVec4函数的参数。利用MathUtil::transformVec4函数通过static void transformVec4(const float*m,constfloat*v,float*dst)接口调用MathUtilSSE::transformVec4函数,将m、v和dst传入MathUtilSSE::transformVec4函数的参数。
在MathUtilSSE::transformVec4函数内,执行如下各操作:
1、使用_mm_loadu_ps函数,将V的数据从内存加载到SSE寄存器,这里以tmp命名该寄存器。
2、使用_mm_shuffle_ps函数,从tmp寄存器中获得一个全是V向量中第一个元素的向量col1,即(x,x,x,x)。
3、使用_mm_shuffle_ps函数,从tmp寄存器中获得一个全是V向量中第二个元素的向量col2,即(y,y,y,y)。
4、使用_mm_shuffle_ps函数,从tmp寄存器中获得一个全是V向量中第三个元素的向量col3,即(z,z,z,z)。
5、使用_mm_shuffle_ps函数,从tmp寄存器中获得一个全是V向量中第四个元素的向量col4,即(1,1,1,1)。
6、使用_mm_loadu_ps函数,加载M的第一列数据到SSE寄存器mc1。
7、使用_mm_loadu_ps函数,加载M的第二列数据到SSE寄存器mc2。
8、使用_mm_loadu_ps函数,加载M的第三列数据到SSE寄存器mc3。
9、使用_mm_loadu_ps函数,加载M的第四列数据到SSE寄存器mc4。
10、使用_mm_mul_ps函数计算mc1与col1的乘积,mc2与col2的乘积,并用_mm_add_ps函数将这两个乘积结果相加。
11、使用_mm_mul_ps函数计算mc3与col3的乘积,mc4与col4的乘积,并用_mm_add_ps函数将这两个乘积结果相加。
12、将10、11的两个步骤的相加结果,继续用_mm_add_ps函数相加,得到最终结果,保存到tmp寄存器。
13、使用_mm_storeu_ps函数,将tmp寄存器中的结果,保存到内存地址dst中,即最终结算结果Vs的地址。
本申请实施例通过修改数学库的SSE版本的接口与函数实现方式,使数学库的SSE指令能在普通的x86机器上正确运行起来,以提高数学库整体的运算效率,能一定程度提高游戏帧率,减少了CPU的计算负担。
图30示出了现有技术中数学库逻辑运算函数的CPU占用时间示意图。图30中CPU的占用时间为7.4%。
图31示出了本申请实施例中数学库逻辑运算函数的CPU占用时间示意图。图31中CPU的占用时间为3.8%。因此,对同一个逻辑运算函数,本申请实施例的效率比现有技术的效率快一倍左右。
需要说明的是,对于方法实施例,为了简单描述,故将其都表述为一系列的动作组合,但是本领域技术人员应该知悉,本申请实施例并不受所描述的动作顺序的限制,因为依据本申请实施例,某些步骤可以采用其他顺序或者同时进行。其次,本领域技术人员也应该知悉,说明书中所描述的实施例均属于优选实施例,所涉及的动作并不一定是本申请实施例所必须的。
参照图32,示出了本申请实施例的一种数据处理装置的结构框图。
本申请实施例的数据处理装置包括调用模块3201、读取加载模块3202、运算模块3203和写入模块3204。
调用模块3201,用于调用SSE指令函数,将用于保存原始数据的第一内存地址和用于保存运算结果的第二内存地址传入所述SSE指令函数的参数。
读取加载模块3202,用于利用所述SSE指令函数调用非对齐内存读取接口函数从所述第一内存地址中读取所述原始数据,并将所述原始数据加载到SSE寄存器中。
运算模块3203,用于利用所述SSE指令函数调用逻辑运算函数对所述原始数据进行逻辑运算,并将运算结果保存至所述SSE寄存器中。
写入模块3204,用于利用所述SSE指令函数调用非对齐内存写入接口函数将所述运算结果写入所述第二内存地址。
在一种可选实施方式中,所述读取加载模块3202包括:矩阵加载单元,用于在所述原始数据为单精度浮点类型的矩阵数据时,将所述矩阵数据中的每一列数据加载到一个SSE寄存器中;向量加载单元,用于在所述原始数据为单精度浮点类型的向量数据时,将所述向量数据加载到一个SSE寄存器中。
在一种可选实施方式中,所述调用模块3201包括:第一调用单元,用于利用Mat4类中定义的Mat4指令函数通过统一MathUtil函数接口调用MathUtil类中定义的MathUtil指令函数,将所述第一地址和所述第二地址传入所述MathUtil指令函数的参数;第二调用单元,用于利用所述MathUtil指令函数通过第一SSE函数接口调用MathUtilSSE类中定义的所述SSE指令函数,将所述第一地址和所述第二地址传入所述SSE指令函数的参数。
在一种可选实施方式中,所述装置还包括:删除模块,用于删除MathUtil.h头文件中定义的第二SSE函数接口;所述第二SSE函数接口的参数为__m128类型传递;定义模块,用于在所述MathUtilSSE类中定义所述第一SSE函数接口;所述第一SSE函数接口的参数为内存地址传递。
在一种可选实施方式中,所述装置还包括:添加模块,用于在所述MathUtil指令函数中添加调用所述SSE指令函数的SSE实现语句;所述第二调用单元,用于利用所述MathUtil指令函数执行所述SSE实现语句,通过第一SSE函数接口调用MathUtilSSE类中定义的SSE指令函数,将所述第一地址和所述第二地址传入所述SSE指令函数的参数。
在一种可选实施方式中,所述装置还包括:第一修改模块,用于将用于声明数据结构与成员函数的头文件中,xmmintrin.h头文件修改为mmintrin.h头文件,并删除union数据结构封装;第二修改模块,用于将MathUtil.h头文件中,xmmintrin.h头文件修改为mmintrin.h头文件;在所述mmintrin.h头文件中定义有所述非对齐内存读取接口函数、所述逻辑运算函数和所述非对齐内存写入接口函数。
对于装置实施例而言,由于其与方法实施例基本相似,所以描述的比较简单,相关之处参见方法实施例的部分说明即可。
在本申请的实施例中,还提供了一种电子设备。例如,电子设备可以被提供为一服务器。该电子设备可以包括一个或多个处理器,以及用于存储处理器可执行指令的存储器,可执行指令例如应用程序。处理器被配置为执行上述的数据处理方法。
在本申请的实施例中,还提供了一种包括指令的非临时性计算机可读存储介质,例如包括指令的存储器,上述指令可由电子设备的处理器执行,以完成上述的数据处理方法。例如,所述非临时性计算机可读存储介质可以是ROM、随机存取存储器(RAM)、CD-ROM、磁带、软盘和光数据存储设备等。
本说明书中的各个实施例均采用递进的方式描述,每个实施例重点说明的都是与其他实施例的不同之处,各个实施例之间相同相似的部分互相参见即可。
本领域内的技术人员应明白,本申请实施例的实施例可提供为方法、装置、或计算机程序产品。因此,本申请实施例可采用完全硬件实施例、完全软件实施例、或结合软件和硬件方面的实施例的形式。而且,本申请实施例可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。
本申请实施例是参照根据本申请实施例的方法、终端设备(系统)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理终端设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理终端设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。
这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理终端设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。
这些计算机程序指令也可装载到计算机或其他可编程数据处理终端设备上,使得在计算机或其他可编程终端设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程终端设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。
尽管已描述了本申请实施例的优选实施例,但本领域内的技术人员一旦得知了基本创造性概念,则可对这些实施例做出另外的变更和修改。所以,所附权利要求意欲解释为包括优选实施例以及落入本申请实施例范围的所有变更和修改。
最后,还需要说明的是,在本文中,诸如第一和第二等之类的关系术语仅仅用来将一个实体或者操作与另一个实体或操作区分开来,而不一定要求或者暗示这些实体或操作之间存在任何这种实际的关系或者顺序。而且,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、物品或者终端设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、物品或者终端设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括所述要素的过程、方法、物品或者终端设备中还存在另外的相同要素。
以上对本申请所提供的一种数据处理方法、装置、电子设备及存储介质,进行了详细介绍,本文中应用了具体个例对本申请的原理及实施方式进行了阐述,以上实施例的说明只是用于帮助理解本申请的方法及其核心思想;同时,对于本领域的一般技术人员,依据本申请的思想,在具体实施方式及应用范围上均会有改变之处,综上所述,本说明书内容不应理解为对本申请的限制。

Claims (12)

1.一种数据处理方法,其特征在于,所述方法包括:
修改用于声明数据结构与成员函数的头文件,包括:将xmmintrin.h头文件修改为mmintrin.h头文件,其中,mmintrin.h头文件中定义有非对齐内存读取接口函数、逻辑运算函数、非对齐内存写入接口函数,以及删除Cocos2dx游戏引擎自带的实现SSE指令的union封装方式,其中,所述union封装方式使得__m128数据类型与原始数据共享内存;
调用SSE指令函数,将用于保存原始数据的第一内存地址和用于保存运算结果的第二内存地址传入所述SSE指令函数的参数;
利用所述SSE指令函数调用非对齐内存读取接口函数从所述第一内存地址中读取所述原始数据,并将所述原始数据加载到SSE寄存器中;
利用所述SSE指令函数调用逻辑运算函数对所述原始数据进行逻辑运算,并将运算结果保存至所述SSE寄存器中;
利用所述SSE指令函数调用非对齐内存写入接口函数将所述运算结果写入所述第二内存地址,以使得Cocos2dx数学库的SSE指令能在普通的x86机器上正确运行起来。
2.根据权利要求1所述的方法,其特征在于,所述将所述原始数据加载到SSE寄存器中的步骤,包括:
在所述原始数据为单精度浮点类型的矩阵数据时,将所述矩阵数据中的每一列数据加载到一个SSE寄存器中;
在所述原始数据为单精度浮点类型的向量数据时,将所述向量数据加载到一个SSE寄存器中。
3.根据权利要求1所述的方法,其特征在于,所述调用SSE指令函数,将用于保存原始数据的第一内存地址及用于保存运算结果的第二内存地址传入所述SSE指令函数的参数的步骤,包括:
利用Mat4类中定义的Mat4指令函数通过统一MathUtil函数接口调用MathUtil类中定义的MathUtil指令函数,将所述第一内存地址和所述第二内存地址传入所述MathUtil指令函数的参数;
利用所述MathUtil指令函数通过第一SSE函数接口调用MathUtilSSE类中定义的所述SSE指令函数,将所述第一内存地址和所述第二内存地址传入所述SSE指令函数的参数。
4.根据权利要求3所述的方法,其特征在于,所述方法还包括:
删除MathUtil.h头文件中定义的第二SSE函数接口;所述第二SSE函数接口的参数为__m128类型传递;
在所述MathUtilSSE类中定义所述第一SSE函数接口;所述第一SSE函数接口的参数为内存地址传递。
5.根据权利要求3所述的方法,其特征在于,所述方法还包括:
在所述MathUtil指令函数中添加调用所述SSE指令函数的SSE实现语句;
所述利用所述MathUtil指令函数通过第一SSE函数接口调用MathUtilSSE类中定义的SSE指令函数的步骤,包括:
利用所述MathUtil指令函数执行所述SSE实现语句,通过第一SSE函数接口调用MathUtilSSE类中定义的SSE指令函数。
6.一种数据处理装置,其特征在于,所述装置包括:
修改模块,用于修改用于声明数据结构与成员函数的头文件,包括:将xmmintrin.h头文件修改为mmintrin.h头文件,其中,mmintrin.h头文件中定义有非对齐内存读取接口函数、逻辑运算函数、非对齐内存写入接口函数,以及删除Cocos2dx游戏引擎自带的实现SSE指令的union封装方式,其中,所述union封装方式使得__m128数据类型与原始数据共享内存;
调用模块,用于调用SSE指令函数,将用于保存原始数据的第一内存地址和用于保存运算结果的第二内存地址传入所述SSE指令函数的参数;
读取加载模块,用于利用所述SSE指令函数调用非对齐内存读取接口函数从所述第一内存地址中读取所述原始数据,并将所述原始数据加载到SSE寄存器中;
运算模块,用于利用所述SSE指令函数调用逻辑运算函数对所述原始数据进行逻辑运算,并将运算结果保存至所述SSE寄存器中;
写入模块,用于利用所述SSE指令函数调用非对齐内存写入接口函数将所述运算结果写入所述第二内存地址,以使得Cocos2dx数学库的SSE指令能在普通的x86机器上正确运行起来。
7.根据权利要求6所述的装置,其特征在于,所述读取加载模块包括:
矩阵加载单元,用于在所述原始数据为单精度浮点类型的矩阵数据时,将所述矩阵数据中的每一列数据加载到一个SSE寄存器中;
向量加载单元,用于在所述原始数据为单精度浮点类型的向量数据时,将所述向量数据加载到一个SSE寄存器中。
8.根据权利要求6所述的装置,其特征在于,所述调用模块包括:
第一调用单元,用于利用Mat4类中定义的Mat4指令函数通过统一MathUtil函数接口调用MathUtil类中定义的MathUtil指令函数,将所述第一内存地址和所述第二内存地址传入所述MathUtil指令函数的参数;
第二调用单元,用于利用所述MathUtil指令函数通过第一SSE函数接口调用MathUtilSSE类中定义的所述SSE指令函数,将所述第一内存地址和所述第二内存地址传入所述SSE指令函数的参数。
9.根据权利要求8所述的装置,其特征在于,所述装置还包括:
删除模块,用于删除MathUtil.h头文件中定义的第二SSE函数接口;所述第二SSE函数接口的参数为__m128类型传递;
定义模块,用于在所述MathUtilSSE类中定义所述第一SSE函数接口;所述第一SSE函数接口的参数为内存地址传递。
10.根据权利要求8所述的装置,其特征在于,所述装置还包括:
添加模块,用于在所述MathUtil指令函数中添加调用所述SSE指令函数的SSE实现语句;
所述第二调用单元,用于利用所述MathUtil指令函数执行所述SSE实现语句,通过第一SSE函数接口调用MathUtilSSE类中定义的SSE指令函数,将所述第一内存地址和所述第二内存地址传入所述SSE指令函数的参数。
11.一种电子设备,其特征在于,包括:
处理器;
用于存储处理器可执行指令的存储器;
其中,所述处理器被配置为执行如权利要求1-5任一项所述的数据处理方法。
12.一种非临时性计算机可读存储介质,其特征在于,当所述存储介质中的指令由电子设备的处理器执行时,使得电子设备能够执行如权利要求1-5任一项所述的数据处理方法。
CN201910290213.5A 2019-04-11 2019-04-11 数据处理方法、装置、电子设备及存储介质 Active CN110038301B (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN201910290213.5A CN110038301B (zh) 2019-04-11 2019-04-11 数据处理方法、装置、电子设备及存储介质

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN201910290213.5A CN110038301B (zh) 2019-04-11 2019-04-11 数据处理方法、装置、电子设备及存储介质

Publications (2)

Publication Number Publication Date
CN110038301A CN110038301A (zh) 2019-07-23
CN110038301B true CN110038301B (zh) 2022-09-30

Family

ID=67276826

Family Applications (1)

Application Number Title Priority Date Filing Date
CN201910290213.5A Active CN110038301B (zh) 2019-04-11 2019-04-11 数据处理方法、装置、电子设备及存储介质

Country Status (1)

Country Link
CN (1) CN110038301B (zh)

Families Citing this family (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN112685413A (zh) * 2020-12-28 2021-04-20 北京像素软件科技股份有限公司 一种游戏配置表的读取方法、装置、存储介质及电子设备

Citations (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN109327530A (zh) * 2018-10-31 2019-02-12 网易(杭州)网络有限公司 一种信息处理方法、装置、电子设备和存储介质

Family Cites Families (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN101216755B (zh) * 2008-01-02 2011-10-12 中国科学院计算技术研究所 Risc处理器及其浮点寄存器的非对齐访存方法
US9336180B2 (en) * 2011-04-07 2016-05-10 Via Technologies, Inc. Microprocessor that makes 64-bit general purpose registers available in MSR address space while operating in non-64-bit mode

Patent Citations (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN109327530A (zh) * 2018-10-31 2019-02-12 网易(杭州)网络有限公司 一种信息处理方法、装置、电子设备和存储介质

Non-Patent Citations (1)

* Cited by examiner, † Cited by third party
Title
应用SIMD并行技术的SHA-1加密算法的批量实现;陈亦欢等;《重庆理工大学学报(自然科学)》;20120715(第07期);全文 *

Also Published As

Publication number Publication date
CN110038301A (zh) 2019-07-23

Similar Documents

Publication Publication Date Title
CN109194960B (zh) 一种图像帧渲染方法、装置及电子设备
US11941381B2 (en) Method for compiling from a high-level scripting language to a blockchain native scripting language
US6995765B2 (en) System, method, and computer program product for optimization of a scene graph
US8823718B2 (en) Systems and methods for downloading algorithmic elements to a coprocessor and corresponding techniques
US7839410B1 (en) Parameter buffer objects for shader parameters in a graphics library
JP2010535393A (ja) グラフィックス・システムにおける可変長の圧縮と関連付けのための方式
CN114025238B (zh) 基于Linux服务器原生安卓应用云端虚拟化方法
WO2016040716A1 (en) Render-time linking of shaders
US20210200608A1 (en) Methods and apparatus to facilitate improving processing of machine learning primitives
CN105190701A (zh) 基于原语的合成
CN110806847A (zh) 一种分布式多屏幕显示方法、装置、设备及系统
CN111798545A (zh) 骨骼动画的播放方法、装置、电子设备和可读存储介质
CN111414150B (zh) 游戏引擎渲染方法、装置、电子设备及计算机存储介质
CN110038301B (zh) 数据处理方法、装置、电子设备及存储介质
CN115908685A (zh) 一种场景渲染方法、装置、设备和存储介质
CN108389153B (zh) 一种视图加载的方法及终端设备
CN113743573A (zh) 用于访问和利用压缩数据及其状态信息的技术
EP3745258A1 (en) Rendering optimisation
CN116909511A (zh) 提升gpu双缓冲显示效率的方法、装置及存储介质
CN109597611B (zh) 前端数据流控制组件开发系统、方法、设备及存储介质
CN114247138B (zh) 图像渲染方法、装置、设备及存储介质
CN108572593B (zh) 跨平台卷积神经网络控制系统及方法、信息数据处理终端
KR20210055278A (ko) 하이브리드 비디오 코딩 방법 및 시스템
US11270493B2 (en) Controlling rendering operations by shader buffer identification
CN112732252A (zh) 一种动态生成ui的方法、装置和电子设备

Legal Events

Date Code Title Description
PB01 Publication
PB01 Publication
SE01 Entry into force of request for substantive examination
SE01 Entry into force of request for substantive examination
GR01 Patent grant
GR01 Patent grant