C++性能优化系列——百倍加速比的矩阵转置性能调优

2023-10-29

打算写一个矩阵转置分别在CPU和GPU平台的性能优化的系列,在最开始把测试环境等一些基本情况交代清楚,并在这里持续更新优化的结果。

机器配置

为了方便各位对比性能,介绍一下我的测试机器配置。
CPU Intel 9900k,程序主要与主频和缓存密切相关,参考如下:
在这里插入图片描述
在这里插入图片描述

公用函数

void TestTranspose(int i,int iAlign,int iVerify)
	{
		/*typedef*/ void (*Funcp[20])(unsigned char*, unsigned char*);
		void (*TargetFunc)(unsigned char*, unsigned char*);
		Funcp[0] = SimdTransposeBlock16;
		Funcp[1] = SimdTransposeBlock16Pad;
		Funcp[2] = SimdTransposeBlock8ColPad;
		Funcp[3] = SimdTransposeBlock8RowPad;
		Funcp[4] = SimdTransposeBlock16PadParallel;
		Funcp[5] = SimdTransposeBlock8RowPadPrefetch;
		Funcp[6] = SimdTransposeBlock8RowPPP;
		Funcp[7] = IPPTranspose;
		TargetFunc = Funcp[i];
		unsigned char* pSource;
		unsigned char* pTarget;
		
		if (iAlign)
		{
			pSource = (unsigned char*)malloc(sizeof(unsigned char) * NSLICE);
			for (int irow = 0; irow < NROW; ++irow)
			{
				memset(pSource + irow * NCOL, irow % 256, sizeof(unsigned char) * NCOL);//按照字节赋值
			}

			pTarget = (unsigned char*)malloc(sizeof(unsigned char) * NSLICE);
			for (int irow = 0; irow < NROW; ++irow)
			{
				memset(pTarget + irow * NCOL, irow % 256, sizeof(unsigned char) * NCOL);//按照字节赋值
			}
		}
		else
		{
			pSource = (unsigned char*)malloc(sizeof(unsigned char) * NREALCOL * NROW);
			for (int irow = 0; irow < NROW; ++irow)
			{
				memset(pSource + irow * (NREALCOL), irow % 256, sizeof(unsigned char) * (NREALCOL));//按照字节赋值
			}
			
			pTarget = (unsigned char*)malloc(sizeof(unsigned char) * NSLICE);
			for (int irow = 0; irow < NROW; ++irow)
			{
				memset(pTarget + irow * NCOL, irow % 256, sizeof(unsigned char) * NCOL);//按照字节赋值
			}
		}
		TargetFunc(pSource, pTarget);

		/*unsigned char* pNavi;
		InitMem(pNavi);
		
		if (iAlign)
		{
			NavTranspose(pSource, pNavi);
			Verify(pNavi, pTarget);
		}
		else
		{
			NavTransposePad(pSource, pNavi);
			Verify(pNavi, pTarget);
		}
		
		FreeMem(pNavi);*/

		FreeMem(pTarget);
		FreeMem(pSource);
	}

优化情况

CPU平台上对元素为char类型,尺寸为1024 * 1024,内存1M的矩阵转置,分别从内存访问,向量化,多线程并行化三个角度优化,执行情况如下:

优化手段 执行时间(ms)
读内存连续 2.68945
写内存连续 1.5498
写内存连续+分块 0.605469
写内存连续+分块+内存填充 0.367188
写内存连续+分块+内存填充+多线程 0.105469
Intrinsic+写内存连续+分块+内存填充 0.0732422
Intrinsic+写内存连续+分块+内存填充+寄存器优化 0.0695312
Intrinsic+写内存连续+分块+内存填充+寄存器优化+预取 0.0669922
Intrinsic+写内存连续+分块+内存填充+寄存器优化+预取+多线程 0.0200195
单线程+IPP 0.0822266

性能对比:
1.在CPU平台上原始转置方法执行时间:2.68945ms,最终优化转置方法执行时间:0.0200195ms,得到加速比约135倍。
2.单线程下与Intel IPP转置函数对比性能,其中IPP 0.0822266ms,Intrinsic最快达到0.0669922ms,速度快于IPP。获得加速比为1.227

传送门

CPU性能优化系列——矩阵转置(一)访问内存顺序带来的性能差异

CPU性能优化系列——矩阵转置(二)循环分块优化缓存访问

CPU性能优化系列——矩阵转置(三)内存填充避免缓存抖动

CPU性能优化系列——矩阵转置(四)OpenMP并行计算

CPU性能优化系列——矩阵转置(六)Intrinsic转置实现与Core Bound优化

CPU性能优化系列——矩阵转置(七)Intrinsic 内存预取与OpenMP多线程并行化

CPU性能优化系列——矩阵转置(八)IPP转置API性能测试

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

C++性能优化系列——百倍加速比的矩阵转置性能调优 的相关文章

  • Java 反射性能

    使用反射创建对象而不是调用类构造函数是否会导致任何显着的性能差异 是的 一点没错 通过反射查找类是 按幅度 更贵 Quoting Java关于反射的文档 http java sun com docs books tutorial refle
  • 如何加快 Java VM (JVM) 的启动时间?

    我正在运行启动多个 JVM 进程的测试 与 JVM 内运行的实际测试时间相比 JVM 的总结启动时间非常重要 我怎样才能加快速度 我已经使用了 client 选项 这确实有帮助 但没有我想要的那么多 还有其他方法吗 比如预加载一堆 JVM
  • 在 R 中,为什么 sum 与其他方法(例如 cumsum)相比如此慢?

    我正在尝试实现一个需要非常快的函数 主要是因为它一遍又一遍地处理巨大的数据帧 R 总是让我感到困惑 为什么它有时有点慢 而有时又慢得离谱 不幸的是 它从来都不快 不管怎样 我一直认为 如果可能的话 当以某种方式推入 apply sapply
  • 频繁插入已排序的集合

    我已经对集合 列表 进行了排序 并且我需要始终保持其排序 我目前在我的集合上使用 List BinarySearch 然后在正确的位置插入元素 我也尝试过在每次插入后对列表进行排序 但性能不可接受 有没有一种解决方案可以提供更好的性能 也许
  • 每个存储桶的最大沙发底座视图数

    假设存储桶中有大量数据 gt 100GB gt 100M 文档 gt 12 种文档类型 并且假设每个视图仅适用于一种文档类型 那么每个存储桶有多少视图就太多了 或者以另一种方式问 在什么时候应该将某些文档类型拆分到单独的存储桶中 以节省处理
  • 如何使用 Java2D 创建硬件加速图像?

    我正在尝试创建一个快速图像生成器 它可以执行大量 2d 转换和形状渲染 因此我尝试使用 BufferedImage 然后获取 Graphics2D 对象来执行所有绘图 我现在主要关心的是 make 速度非常快 所以我创建一个像这样的 Buf
  • 用 OpenCL C 编写快速线性系统求解器

    我正在编写一个 OpenCL 内核 它将涉及求解线性系统 目前我的内核太慢了 提高线性系统部分的性能似乎是一个不错的起点 我还应该注意 我并没有尝试使我的线性求解器并行 我正在研究的问题在宏观层面上已经是令人尴尬的并行 以下是我编写的 C
  • Java中精确的时间测量

    Java 提供了两种获取当前时间的方法 System nanoTime and System currentTimeMillis 第一个给出的结果以纳秒为单位 但实际精度比这要差得多 许多微秒 JVM 是否已经为每台特定机器提供了最佳的价值
  • 为什么 Sleep() 会使后续代码减慢 40 毫秒?

    我最初是在 coderanch com 上询问这个问题的 所以如果您尝试在那里帮助我 谢谢 并且不必重复这个努力 不过 coderanch com 主要是一个 Java 社区 而且 经过一些研究 这似乎确实是一个 Windows 问题 因此
  • “ab”或“httperf”哪个更适合检查网站的性能?

    到目前为止我知道 ab 和 httperf 两者都可以检查网站的性能 这个比那个好吗 嗯 这确实有点取决于您想要检查的内容 但我自己总是使用 httperf 关键区别在于 httperf 尝试以给定速度发送连续的请求流 无论请求是否得到答复
  • 什么是粗网格搜索和细网格搜索?

    我正在读这个答案 用于 2D 碰撞检测的四叉树的高效 且解释良好 实现 https stackoverflow com questions 41946007 efficient and well explained implementati
  • 将所有奇数位置的元素移动到左半部分,将偶数位置的元素移动到右半部分

    给定一个包含正整数和负整数的数组 将所有奇数索引元素移动到左侧 将偶数索引元素移动到右侧 问题的难点是在维持秩序的同时就地做 e g 7 5 6 3 8 4 2 1 输出应该是 5 3 4 1 7 6 8 2 如果顺序不重要 我们可以使用快
  • 更快地评估从右到左的矩阵乘法

    我注意到以二次形式评估矩阵运算右到左明显快于左到右在 R 中 取决于括号的放置方式 显然它们都执行相同的计算量 我想知道为什么会这样 这与内存分配有什么关系吗 A 5000 5000 B 5000 2 A matrix runif 5000
  • 从 dask 数据框中的日期时间序列获取年份和星期?

    如果我有一个 Pandas 数据框和一个日期时间类型的列 我可以按如下方式获取年份 df year df date dt year 对于 dask 数据框 这是行不通的 如果我先计算 像这样 df year df date compute
  • 在高负载站点中使用 PHP 的策略

    在你回答这个问题之前 我从未开发过任何足够流行的东西来达到高服务器负载 把我当作 叹气 一个刚刚登陆地球的外星人 尽管我了解 PHP 和一些优化技术 我正在开发一个工具PHP如果效果好的话 可以吸引相当多的用户 然而 虽然我完全有能力开发该
  • 为什么 istream/ostream 慢

    于 50 40http channel9 msdn com Events GoingNative 2013 Writing Quick Code in Cpp Quickly http channel9 msdn com Events Go
  • C# 代码在 IIS 上运行速度快,但在 Mono 上运行速度慢 - 如何改进?

    我有一个 ASP NET 应用程序 它在我的 Windows 开发计算机上运行良好 不过 服务器是运行 Mono 的 Linux 一旦上传 相同的代码在 Windows 上的运行速度会比在 Windows 机器上慢 4 到 5 倍 例如 一
  • 为什么线程本地存储不使用页表映射来实现?

    我希望使用 C 11thread local将非常频繁地访问的每线程布尔标志的关键字 然而 大多数编译器似乎都使用一个表来实现线程本地存储 该表将整数 ID 槽 映射到当前线程上的变量地址 此查找将发生在性能关键的代码路径内 因此我对其性能
  • 在Python中将大文件(25k条目)加载到dict中很慢?

    我有一个大约有 25000 行的文件 它是 s19 格式的文件 每行就像 S214780010 00802000000010000000000A508CC78C 像这样的事情怎么样 我做了一个测试文件 只有一行S21478001000802
  • 为什么 LinkedList 通常比 List 慢?

    我开始在我的一些 C 算法中使用一些 LinkedList 而不是列表 希望能够加快速度 然而 我注意到他们只是感觉更慢 像任何优秀的开发人员一样 我认为我应该尽职调查并验证我的感受 所以我决定对一些简单的循环进行基准测试 我认为用一些随机

随机推荐

  • C#中List常用方法:判断存在、查找、排序

    项目常用List来进行数据操作管理 有一些方法经常百度 所以这里记录下 目录 1 List判断元素是否存在 返回bool 2 List查找 返回对象 3 List排序 4 对象属性打印 5 List 其他方法 1 List判断元素是否存在
  • 程序员的自我修养——链接,装载与库

    章节目录 静态链接 编译和链接 目标文件 静态链接 windows COFF 装载和动态链接 可执行文件的装载与进程 动态链接 Linux共享库的组织 Windows下的动态链接 库与运行库 内存 运行库 系统调用与API 运行库实现 一
  • 【C++入门】引用符&详解

    1 C 的 引用符介绍 1 符号在C语言中表示取地址运算 2 C 对 符号进行拓展 符号新增了引用的用法 3 声明引用时 必须同时对其进行初始化 4 引用声明完毕后 相当于目标变量有两个名称 引用名就相当于变量的别名 操作引号名就相当于操作
  • 【深度解析→博文总结】李宏毅机器学习2023作业02Classification(Framewise Phoneme Prediction)

    文章目录 系列文章 简要说明 视频分享 作业详情 调参记录 Simple Baseline 0 49798 Medium Baseline 0 66440 Stong Baseline 0 74944 Boss Baseline 0 830
  • html制作电影界面,电影网站界面设计HTML_CSS模板

    实例简介 简单生活 希望对大家有用 要觉得本资源有价值请分享给您的朋友 生活就是人来人往 分享越多 收获越多 作者 天天ASP家园 实例截图 核心代码 7c828d9e b4a1 48fc be7b 81a2137edae2 电影网站界面设
  • ​​​​​​​三个案例帮你彻底了解反馈电路中的相位补偿

    转自于http www elecfans com d 669847 html 三个案例帮你彻底了解反馈电路中的相位补偿 2004年 帮朋友做镍氢充电器 利用镍氢电池充满电时电压有一个微小的下降这个特点来识别是否已经充满 比如1 2V的镍氢电
  • 程序员戴耳机究竟在听什么,看完真相,我惊了!

    今天 某妹子突然凑到我的耳边轻声说说 我们公司的程序员 清一色的戴着耳机 你说他们是不是故意不想听我们提的需求 我很方 因为我也喜欢戴耳机 思考ing 思考了一秒钟后 一本正经的和妹子说 你这么漂亮 怎么会呢 戴耳机可能只是他们的习惯罢了
  • String详解

    String类的理解 什么是String类 String类实现了Serializable接口 对象可以被序列化 序列化之后 对象可以进行网络传输 或者持久化 String类实现的Comparable接口 对象可以比较大小 String类实现
  • GoLang之搭建Web服务器

    2014 02 05 wcdj 0 摘要 之前总结过如何使用Perl搭建Web服务 Web服务器的实现 最小的Perl Web服务器 本文介绍如何使用GoLang搭建Web服务 Go语言提供了一个完善的net http包 通过这个http包
  • 将yolov3.pth转换为onnx并进行推理

    前言 最近训练了一个yolov3检测模型 需要将保存好的 pth文件转换为onnx并且写一个inference过程 于是学习了一下onnx的知识并记录下来 用到的工具 onnx 安装方法 pip install onnx onnxrunti
  • DVI-A、DVI-D、DVI-I接口定义、DVI接口图和DVI接口标准介绍

    dvi接口义 DVI接口图片 DVI接口标准介绍 dvi hdmi接口定义 DVI 的定义 DVI A 就是与 VGA 规范一样的 包括 RGBHV 信号线的模拟接口 RGB 是什么不用赘述了吧 HV 分别是水平 和 垂直 扫描的 行同步
  • springboot集成log4j日志

    一 新建log4j properties配置文件 配置内容如下 log4j rootLogger CONSOLE info error DEBUGlog4j rootLogger info error CONSOLE DEBUGlog4j
  • 端口扫描

    常见的扫描类型有以下几种 秘密扫描 秘密扫描是一种不被审计工具所检测的扫描技术 它通常用于在通过普通的防火墙或路由器的筛选 filtering 时隐藏自己 秘密扫描能躲避IDS 防火墙 包过滤器和日志审计 从而获取目标端口的开放或关闭的信息
  • 终结 Java 空指针异常!优雅方案解析与案例演示

    目录 引言 产生原因 优雅解析 代码示例 优雅解决方案一 条件判断 优雅解决方案二 断言与异常处理 优雅解决方案三 使用 Objects 类的 requireNonNull 方法 优雅解决方案三 Optional 类的妙用 总结 引言 Nu
  • 【uniapp】结构

    目录 uniapp 结构 1 1 pages json 1 2 uni modules 文件夹 1 3 store 文件夹 1 4 manifest json 1 5 App vue 1 6 main js 1 7 pages 文件夹 1
  • Eureka是干什么的?

    Eureka是干什么的 Eureka是干什么的 注册中心 透明化路由 Eureka 基础架构 Eureka 交互流程及原理 简单实用摘要说明 Eureka的元数据 Eureka客户端详解 我保护机制 源码 自动装配实现 Eureka是干什么
  • 雷赛智能24校招-算法/嵌入式/fpga/机械/电子/自动化

    题解 相逆叶子 function TreeNode x this val x this left null this rig 题解 售价的中位数 import java util public class Solution 代码中的类名 方
  • H5清理微信缓存的方案

    背景 H5移动端开发 尤其是基于微信的公号开发 往往伴随着很严重的缓存问题 影响测试和开发人员的感情 为了解决这个问题 找到以下清除缓存的方式 希望对增进开发和测试人员的感情有所作用 方案 安卓端清除缓存的方法如下 http debugx5
  • SpringBoot ——kafka消费多个不同服务器地址消息解决方案

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 一 背景 在springboot实际项目开发中 kafka可能需要消费多个不同服务器地址的数据 这时懂得如何进行配置就显得非常必要了 二 配置 1 KafkaConfig
  • C++性能优化系列——百倍加速比的矩阵转置性能调优

    打算写一个矩阵转置分别在CPU和GPU平台的性能优化的系列 在最开始把测试环境等一些基本情况交代清楚 并在这里持续更新优化的结果 机器配置 为了方便各位对比性能 介绍一下我的测试机器配置 CPU Intel 9900k 程序主要与主频和缓存