[QNX] mmap+cache/nocache+memcpy/asm_memcpy速度对比

mmap nocache介绍

以linux系统的nocache介绍:

在Linux系统中,使用mmap映射文件到内存时可以指定不使用缓存。这可以通过在调用mmap时将MAP_NOCACHE标志传递给mmap函数来实现。
MAP_NOCACHE标志告诉内核不要将映射的内存页缓存到文件系统缓存中,而是直接将内存与文件关联。这对于需要频繁读写大量数据的应用程序是有益的,因为它避免了在读写数据时额外的缓存开销。

例如:

#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
int main() {int fd = open("file.txt", O_RDWR);char *ptr = mmap(NULL, 100, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_NOCACHE, fd, 0);// use ptr to read and write data directly from/to the file...munmap(ptr, 100);close(fd);return 0;
}

qnx系统介绍:
https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/p/posix_typed_mem_open.html

数据

memcpy cached speed: 2133.333333 MB/s (千兆级别)
memcpy nocached speed: 116.363636 MB/s (百兆级别)
invalidate memcpy cached speed: 1333.333333 MB/s (千兆级别)
invalidate memcpy nocached speed: 112.280702 MB/s (百兆级别)
asm memcpy cached speed: 2133.333333 MB/s (千兆级别)
asm memcpy nocached speed: 225.352113 MB/s (百兆级别)

名词

mmap cached指mmap使用PROT_READ | PROT_WRITE这个flag

mmap nocached是指mmap使用PROT_READ | PROT_WRITE | PROT_NOCACHE这个flag

  • memcpy是指单纯调用memcpy,如
for (size_t i = 0; i < count; i++) {memcpy(dst, src[i], bytes);
}
  • invalidate memcpy是指memcpy前先用msync设置共享内存属性,如
for (size_t i = 0; i < count; i++) {msync(src[i], bytes, MS_INVALIDATE);memcpy(dst, src[i], bytes);
}
  • asm memcpy是指汇编版本的memcpy,如
inline void aarch64_fast_memcpy(void *dst, const void *src, size_t size) {
#ifdef _QNX_void *ss = (void *)src, *dd = (void *)dst;size_t sz = size;asm volatile("loop_start: ""ldp q3, q4,[%0,#0x0]\n""ldp q5, q6,  [%0,#0x20]\n""ldp q7, q8,  [%0,#0x40]\n""ldp q9, q10, [%0,#0x60]\n""stp q3, q4,  [%1,#0x0]\n""stp q5, q6,  [%1,#0x20]\n""stp q7, q8, [%1,#0x40]\n""stp q9, q10, [%1,#0x60]\n""add %0, %0, #0x80\n""add %1, %1, #0x80\n""subs %2, %2, #0x80\n""b.ne loop_start\n""dsb sy\n": /* no output */: "r"(ss), "r"(dd), "r"(sz));
#endif
}
// ......   
for (size_t i = 0; i < count; i++) {aarch64_fast_memcpy(dst, src[i], bytes);
}

(完整代码见后面长源码文件)

结论

cached情况下:memcpy和asm memcpy差不多快(没有明显区别),invalidate memcpy最慢。

nocached情况下,asm memcpy最快,memcpy第二快,invalidate memcpy最慢。

测试源码

// mmap_memcpy.c
#include <errno.h>
#include <fcntl.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>#ifndef _QNX_
#define PROT_NOCACHE 0
#endifinline void aarch64_fast_memcpy(void *dst, const void *src, size_t size) {
#ifdef _QNX_void *ss = (void *)src, *dd = (void *)dst;size_t sz = size;asm volatile("loop_start: ""ldp q3, q4,[%0,#0x0]\n""ldp q5, q6,  [%0,#0x20]\n""ldp q7, q8,  [%0,#0x40]\n""ldp q9, q10, [%0,#0x60]\n""stp q3, q4,  [%1,#0x0]\n""stp q5, q6,  [%1,#0x20]\n""stp q7, q8, [%1,#0x40]\n""stp q9, q10, [%1,#0x60]\n""add %0, %0, #0x80\n""add %1, %1, #0x80\n""subs %2, %2, #0x80\n""b.ne loop_start\n""dsb sy\n": /* no output */: "r"(ss), "r"(dd), "r"(sz));
#endif
}off_t offset(unsigned int bytes) {static off_t base_offset = 0x1E000000;off_t return_base_offset = base_offset;base_offset += bytes;return return_base_offset;
}void *mmap_memory(unsigned int bytes, int flag) {int fd = open("/dev/mem", O_RDWR | O_SYNC);if (fd < 0) {printf("open /dev/mem failed: %s\n", strerror(errno));}void *ptr = mmap(NULL, bytes, flag, MAP_SHARED, fd, offset(bytes));close(fd);if (MAP_FAILED == ptr) {printf("mmap failed: %s\n", strerror(errno));}return ptr;
}void *mmap_memory_cached(unsigned int bytes) {return mmap_memory(bytes, PROT_READ | PROT_WRITE);
}void *mmap_memory_nocached(unsigned int bytes) {return mmap_memory(bytes, PROT_READ | PROT_WRITE | PROT_NOCACHE);
}// if C++
#ifdef __cplusplus
#include <chrono>
using namespace std::chrono;
#define start() auto start_ = high_resolution_clock::now();
#define end()                                                                  \auto end_ = high_resolution_clock::now();                                  \double bytes_mb = bytes * count / 1024.0 / 1024.0;                         \double cost_ns = duration_cast<nanoseconds>(end_ - start_).count();        \double mps = bytes_mb / cost_ns * 1e9;#else
#include <time.h>
#include <unistd.h>
double time_diff_ns(struct timespec start, struct timespec end) {return (end.tv_sec - start.tv_sec) * 1e9 + (end.tv_nsec - start.tv_nsec);
}
#define start()                                                                \struct timespec start_, end_;                                              \clock_gettime(CLOCK_REALTIME, &start_);#define end()                                                                  \clock_gettime(CLOCK_REALTIME, &end_);                                      \double bytes_mb = bytes * count / 1024.0 / 1024.0;                         \double cost_ns = time_diff_ns(start_, end_);                               \double mps = bytes_mb / cost_ns * 1e9;#endifdouble memcpy_speed(void *dst, void **src, unsigned int bytes,unsigned int count) {start();for (size_t i = 0; i < count; i++) {memcpy(dst, src[i], bytes);}end();return mps;
}double invalidate_memcpy_speed(void *dst, void **src, unsigned int bytes,unsigned int count) {start();for (size_t i = 0; i < count; i++) {msync(src[i], bytes, MS_INVALIDATE);memcpy(dst, src[i], bytes);}end();return mps;
}double asm_memcpy_speed(void *dst, void **src, unsigned int bytes,unsigned int count) {start();for (size_t i = 0; i < count; i++) {aarch64_fast_memcpy(dst, src[i], bytes);}end();return mps;
}int main(int argc, char *argv[]) {const unsigned int count = 2;unsigned int bytes = 128 * 1024; // 128 KBif (argc > 1) {bytes = atoi(argv[1]) * 1024;}printf("bytes: %d\n", bytes);printf("count: %d\n", count);void *mmap_cached_src[count];void *mmap_nocached_src[count];for (size_t i = 0; i < count; i++) {mmap_cached_src[i] = mmap_memory_cached(bytes);mmap_nocached_src[i] = mmap_memory_nocached(bytes);}void *dst = malloc(bytes);printf("memcpy cached speed: %f MB/s\n",memcpy_speed(dst, mmap_cached_src, bytes, count));printf("memcpy nocached speed: %f MB/s\n",memcpy_speed(dst, mmap_nocached_src, bytes, count));printf("invalidate memcpy cached speed: %f MB/s\n",invalidate_memcpy_speed(dst, mmap_cached_src, bytes, count));printf("invalidate memcpy nocached speed: %f MB/s\n",invalidate_memcpy_speed(dst, mmap_nocached_src, bytes, count));printf("asm memcpy cached speed: %f MB/s dst[0]=%d\n",asm_memcpy_speed(dst, mmap_cached_src, bytes, count), ((char *)dst)[0]);printf("asm memcpy nocached speed: %f MB/s\n",asm_memcpy_speed(dst, mmap_nocached_src, bytes, count));free(dst);for (size_t i = 0; i < count; i++) {munmap(mmap_cached_src[i], bytes);munmap(mmap_nocached_src[i], bytes);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/6762.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nginxconfig.io项目nginx可视化配置--搭建-视频

项目地址 https://github.com/digitalocean/nginxconfig.io搭建视频 nginxconfig.io搭建 nginxconfig.io搭建 展示效果 找到这个项目需要的docker镜像&#xff0c;有项目需要的node的版本 docker pull node:20-alpine运行这个node容器,在主机中挂载一个文件夹到容器中 主机&a…

Python语言例题集(013)

#!/usr/bin/python3 #建立循环链表。 class Node(): def init(self,dataNone): self.datadata self.nextNone n1Node(5) n2Node(15) n3Node(25) n1.nextn2 n2.nextn3 n3.nextn1 ptrn1 counter1 while counter<6: print(ptr.data) ptrptr.next counter1

ES相关性计算原理

了解es搜索过程中的相关性计算原理&#xff0c;对判断当前应用场景是否适合使用es来召回相关结果至关重要。本篇博文尝试对es在每一个节点执行搜索时如何计算query和经由倒排索引查询到的对应字段文本之间的相关性做简要说明。 ES搜索过程&#xff08;节点层面&#xff09; ES…

2024.4.27 —— LeetCode 高频题复盘

目录 102. 二叉树的层序遍历33. 搜索旋转排序数组121. 买卖股票的最佳时机200. 岛屿数量20. 有效的括号88. 合并两个有序数组141. 环形链表46. 全排列236. 二叉树的最近公共祖先 102. 二叉树的层序遍历 题目链接 Python 方法一 # Definition for a binary tree node. # clas…

深入浅出区块链技术:原理、应用与挑战

区块链技术是一种分布式数据库技术&#xff0c;其核心在于提供一个去中心化、不可篡改的数据记录系统。以下是区块链技术的原理、应用和面临的挑战的详细解析&#xff1a; ### 原理 1. **去中心化**&#xff1a;区块链技术不依赖于中央控制点&#xff0c;而是通过网络上的多个…

菜鸡学习netty源码(五)—— EventLoop

1.EventLoop的类关系图 2. EventExecutor /*** 返回自身的对象* Returns a reference to itself.*/OverrideEventExecutor next();/*** 获取所属的EventExecutorGroup* Return the {link EventExecutorGroup} which is the parent of this {link EventExecutor},*/EventExecuto…

利用大语言模型(KIMI)构建智能产品的信息模型

数字化的核心是数字化建模&#xff0c;为一个事物构建数字模型是一件非常繁杂和耗费人工的事情。利用大语言模型&#xff0c;能够轻松地生成设备的信息模型&#xff0c;我们的初步实验表明&#xff0c;只要提供足够的模板&#xff0c;就能够准确地生成设备的数字化模型。 我们尝…

Pytorch 实现 GAN 对抗网络

GAN 对抗网络 GAN&#xff08;Generative Adversarial Network&#xff09;对抗网络指的是神经网络中包括两个子网络&#xff0c;一个用于生成信息&#xff0c;一个用于验证信息。下面的例子是生成图片的对抗网络&#xff0c;一个网络用于生成图片&#xff0c;另一个网络用于验…

debootstrap构建基于Debian的嵌入式系统的rootfs

嵌入式芯片&#xff1a;iMX6ULL 准备环境&#xff1a; 确保您的开发机器已安装debootstrap和qemu-user-static&#xff08;如果您在非ARM机器上构建ARM rootfs&#xff09;。 sudo apt-get updatesudo apt-get install debootstrap qemu-user-static使用debootstrap创建rootf…

[C++基础学习-06]----C++指针详解

前言 指针是一个存储变量地址的变量&#xff0c;可以用来访问内存中的数据。在C中&#xff0c;指针是一种非常有用的数据类型&#xff0c;可以帮助我们在程序中对内存进行操作和管理。 正文 01-指针简介 指针的基本概念如下&#xff1a; 声明指针&#xff1a;使用“*”符…

Python零基础快速入门学习笔记

文章目录 1. 安装python2. 安装vscode3. python语法3.1 流程控制3.1.1 条件语句3.1.2 循环语句 3.2 模块与包3.2.1 模块3.2.2 包 3.3 数据类型3.3.1 数字&#xff08;Number&#xff09;3.3.2 字符串&#xff08;string&#xff09;3.3.3 列表&#xff08;list&#xff09;3.3.…

[单片机课设]十字路口交通灯的设计

题目要求&#xff1a; 模拟交通灯运行情况。南北绿灯亮30秒&#xff0c;南北黄灯亮3秒&#xff0c;东西红灯亮33秒&#xff1b;南北红灯亮33秒&#xff0c;东西绿灯亮30秒&#xff0c;东西黄灯亮3秒&#xff1b;要求数码管同步显示时间的倒计时&#xff0c;用定时器实现延时。…

(HAL)STM32F103C8T6——内部flash模拟EEPROM

内部Flash大部分空间是用来存储烧录进单片机的程序代码&#xff0c;因此可以将非代码等无关区域用来存储数据。项目工程的代码量可以通过Keil uVision5软件底下框查看&#xff0c;如下图所示。一般只需参考代码量&#xff08;Code&#xff09;以及只读数据&#xff08;RO-data&…

某盾BLACKBOX逆向关键点

需要准备的东西&#xff1a; 1、原JS码 2、AST解混淆码 3、token(来源于JSON) 一、原JS码很好获取&#xff0c;每次页面刷新&#xff0c;混淆的代码都会变&#xff0c;这是正常&#xff0c;以下为部分代码 while (Qooo0) {switch (Qooo0) {case 110 14 - 55: {function O0…

C++入门第二节--关键字、命名空间、输入输出

点赞关注不迷路&#xff01;本节涉及c入门关键字、命名空间、输入输出... 1. C关键字 C总计63个关键字&#xff0c;C语言32个关键字 asmdoifreturntrycontinueautodoubleinlineshorttypedefforbooldynamic_castintsignedtypeidpublicbreakelselongsizeoftypenamethrowcaseen…

1.预备知识

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 预备知识 一、C语言和C的发展历史和基本原理二、过程性编程和面向对象编程三、编程语言的标准 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、C…

A Dexterous Hand-Arm Teleoperation System

A Dexterous Hand-Arm Teleoperation System Based on Hand Pose Estimation and Active Vision解读 摘要1. 简介2.相关工作2.1 机器人遥操作2.2 主动视觉&#xff08;Active Vision&#xff09; 3. 硬件设置4. 基于视觉的机器人手部姿态估计4.1 Transteleop4.2 Dataset 5. 主动…

升级OpenSSH版本(安装telnet远程管理主机)

一 OpenSSH是什么 OpenSSH 是 SSH &#xff08;Secure SHell&#xff09; 协议的免费开源实现。SSH协议族可以用来进行远程控制&#xff0c; 或在计算机之间传送文件。而实现此功能的传统方式&#xff0c;如telnet(终端仿真协议)、 rcp ftp、 rlogin、 rsh都是极为不安全的&…

C++奇迹之旅:string类接口详解(上)

文章目录 &#x1f4dd;为什么学习string类&#xff1f;&#x1f309; C语言中的字符串&#x1f309;string考察 &#x1f320;标准库中的string类&#x1f309;string类的常用接口说明&#x1f320;string类对象的常见构造 &#x1f6a9;总结 &#x1f4dd;为什么学习string类…

二维泊松方程(Neumann+Direchliet边界条件)有限元Matlab编程求解|程序源码+说明文本

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现&#xff0c;并提供所有案例完整源码&#xff1b;2.单元…