SIMD高性能算子优化[3]:方阵快速转置

本文介绍了使用SSE指令对4x4矩阵进行行向量转置的方法,对比了传统方法和SSE方法的性能,结果显示SSE方法显著提高了效率。

1. 背景及需求

        由于项目需求及硬件资源约束,笔者需要基于RK3588板端的NEON寄存器,对当前的hot pot算子进行加速实现。作为SIMD指令集小白,笔者不得不从熟悉相关内联函数的使用开始,逐渐揭开SIMD的神秘面纱!该系列博文,以学习过程中涉及的诸多CV类或其他类算子为切入点,结合内联函数及纯汇编代码等进行逐个的精讲及剖析。

2. 实现思路

图1. 4*4矩阵分步转置示意(共计两大步)

如图1所示,4*4矩阵可按照行向量方式划分为4行,后续SSE操作时,以上述的行向量为基本操作单位,数据类型统一为float32。为方便结果的对比,矩阵数值设置如下:

图2. 输入矩阵示意

 因而,其转置后的输出结果应为:

 图3. 输出矩阵示意

3. 相关SSE指令用法及功能说明

本次涉及的内联函数主要包括两大类,即:

(1) _mm_load_ps() / _mm_store_ps() :利用XMM寄存器单次获取/存储4个fp32的浮点型数据;

(2) _mm_unpacklo_ / _mm_unpackhi_():从源XMM寄存器中去除低32(或高32)位数据后,交叉存储在目的寄存器中。以_mm_unpacklo_ps()函数为例,其具体示意如下(其余函数同理):

图4. _mm_unpacklo_ps()函数操作过程说明

4. 源码说明

#include <ctime>
#include <iostream>
#include <chrono>
#include <mmintrin.h>
#include <xmmintrin.h>
#include <emmintrin.h>
#include <x86intrin.h>   

using namespace std;
#define M   4
#define N   4

// 满足内存对齐要求的malloc函数
void* aligned_malloc(size_t size, size_t alignment)
{
	size_t offset = alignment - 1 + sizeof(void*);
	void * originalP = malloc(size + offset);
	size_t originalLocation = reinterpret_cast<size_t>(originalP);
	size_t realLocation = (originalLocation + offset) & ~(alignment - 1);
	void * realP = reinterpret_cast<void*>(realLocation);
	size_t originalPStorage = realLocation - sizeof(void*);
	*reinterpret_cast<void**>(originalPStorage) = originalP;
	return realP;
}

// 内存释放
void aligned_free(void* p)
{
	size_t originalPStorage = reinterpret_cast&l
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值