C++中的内存锁定

news2025/1/19 11:25:51

      内存锁定(memory locking)是确保进程保留在主内存中并且免于分页的一种方法。在实时环境中,系统必须能够保证将进程锁定在内存中,以减少数据访问、指令获取、进程之间的缓冲区传递等的延迟。锁定内存中进程的地址空间有助于确保应用程序的响应时间满足实时要求。作为一般规则,时间关键的进程(time-critical process)应该被锁定到内存中。
      虚拟地址空间(virtual address space)被划分为固定大小的单元(fixed-sized unit),称为页(page)。每个进程通常占用多个页,这些页在进程执行时独立地移入和移出主内存。通常,当进程执行时,进程页的子集驻留在主内存(primary memory)中。
      由于可用的主内存量是有限的,因此分页通常会牺牲一些页即要移入页,必须移出其他页。如果要替换的页在执行期间被修改,则该页将被写入文件区域。该页根据需要被带回主内存,并且在内核检索该页时延迟执行。
      分页通常对当前进程是透明的通过增加物理内存的大小或将页锁定到内存中可以减少分页量。但是,如果进程非常大或者页频繁调入和调出,则调页所需的系统开销可能会降低效率。
      对于实时应用程序来说,拥有足够的内存比非实时应用程序更重要。实时应用程序必须确保进程被锁定到内存中,并且有足够的内存可供实时进程和系统使用。对于关键的实时任务来说,由于分页引起的延迟通常是不可接受的。
      内存锁定适用于进程的地址空间。只有映射到进程地址空间的页才能被锁定到内存中。当进程退出时,页将从地址空间中删除,并且锁也被删除。
      内存锁定有两个主要应用:实时算法和高安全性数据处理。
      页锁定内存无法从RAM移动到交换文件,确保该内存始终驻留在物理内存中。与传统内存相比,它提高了GPU的PCI-Express(CPU和GPU之间的总线) I/O速度。
      NVIDIA的GPU是一个协处理器(co-processor),GPU内核启动、数据初始化和传输均由CPU进行.
      CUDA中有四种类型的内存分配
      1.Pageable memory(可分页内存):主机中分配的内存默认是可分页内存。该内存位置的数据可供主机使用。为了将此数据传输到设备,CUDA运行时会将此内存拷贝到临时固定内存,然后传输到设备内存。因此,存在两次内存传输。因此,这种类型的内存分配和传输速度很慢。GPU无法直接从可分页主机内存访问数据。涉及的函数:malloc, cudaMalloc, cudaMemcpy
      2.Pinned memory(固定内存):也称为页锁定,数据可以直接在主机固定存储器中初始化。与malloc分配的常规可分页主机内存相反。通过这样做,我们可以避免像可分页内存中那样的两次数据传输。这将使该过程更快,但会牺牲主机性能。当数据在固定存储器中初始化时,主机处理的存储器可用性会降低。涉及的函数:cudaMallocHost, cudaMalloc, cudaMemcpy
      优点:
      (1).对于某些设备,页锁定主机内存和设备内存之间的拷贝可以与内核执行同时执行。
      (2).在某些设备上,页锁定主机内存可以映射到设备的地址空间,从而无需将其拷贝到设备内存或从设备内存中拷贝。
      (3).在具有前端总线(front-side bus)的系统上,如果主机内存被分配为页锁定,则主机内存和设备内存之间的带宽(bandwidth)会更高。
      注:页锁定主机内存不会缓存在非I/O一致Tegra设备上。此外,非I/O一致Tegra设备不支持cudaHostRegister。
      3.Mapped memory(映射内存)或Zero copy memory(零拷贝内存):零拷贝内存是映射到设备地址空间的固定内存。主机和设备都可以直接访问该内存。涉及的函数:cudaHostAlloc, cudaHostGetDevicePointer
      优点:
      (1).当设备内存不足时,可以利用主机内存。
      (2).可以避免主机和设备之间显式的数据传输。
      (3).提高PCI-Express传输速率。
      缺点:由于它被映射到设备地址空间,因此数据不会被拷贝到设备内存中。传输将在执行期间发生,这将大大增加处理时间。
      4.Unified memory(统一内存):这将创建一个托管内存池,其中来自该内存池的每个分配都可以在主机和设备上使用相同的地址或指针进行访问。底层系统将数据迁移到主机和设备。涉及的函数:cudaMallocManaged
      优点:无需为所需的设备显式分配和恢复内存。这降低了编程复杂性。
      缺点:在内存管理方面添加了额外的指令.
      RAM(Random Access Memory):随机存取存储器,是一种计算机存储器,它用于临时存储数据和指令,以便在计算机运行时快速访问。RAM可以随时读取和写入数据,而且读取和写入的速度非常快。相比之下,硬盘、闪存等存储设备的数据访问速度要慢得多。RAM通常用于计算机的主存(内存),以便CPU可以快速访问指令和数据。它也用于缓存和其他高速存储设备,以加快数据访问速度。
      linux下的用于内存锁定的函数mlock/mlockall, munlock/munlockall声明如下:

int mlock(const void *addr, size_t len);
int munlock(const void *addr, size_t len);
int mlockall(int flags);
int munlockall(void);

      mlock:锁定从addr开始并持续len字节的地址范围内的页。当调用成功返回时,所有包含指定地址范围的页都保证驻留在RAM中,直到稍后解锁。
      munlock:解锁从addr开始并持续len字节的地址范围内的页。在此调用之后,包含指定内存范围的所有页都可以由内核再次移动到外部交换空间。
      mlockall:锁定映射到调用进程的地址空间的所有页。This includes the pages of the code, data and stack segment, as well as shared libraries, user space kernel data, shared memory, and memory-mapped files. 当调用成功返回时,所有映射的页都保证驻留在RAM中,直到稍后解锁。
      munlockall:解锁映射到调用进程地址空间的所有页.
      mlock和mlockall函数分别将调用进程的部分或全部虚拟地址空间(virtual address space)锁定到RAM中,防止该内存被分页到交换区域(preventing that memory from being paged to the swap area)。munlock和munlockall执行相反的操作,分别解锁调用进程的部分或全部虚拟地址空间,以便在内核内存管理器(kernel memory manager)需要时可以再次交换指定虚拟地址范围内的分页。
      内存锁定和解锁以整页(whole page)为单位进行
      这些函数调用成功时返回0;失败时返回-1,设置errno来指出错误。
      注意
      1.内存锁定不会被通过fork创建的子进程继承(注:现代的Unix系统可能并非这样)。
      2.如果通过munmap取消映射,则会自动删除地址范围(address range)上的内存锁定。
      3.如果锁定了非常多的内存,有些程序可能会因为缺少内存(real memory)而根本无法运行,或者导致系统运行速度更慢。
      4.内存锁定不堆叠(memory locks do not stack),不能两次锁定特定页。
      5.内存锁定持续存在,直到进程退出或应用程序调用相应的munlock或munlockall函数解锁它为止。
      以上内存主要整理自:

      1.https://man7.org/linux/man-pages/man2/mlock.2.html
      2.https://medium.com/analytics-vidhya/cuda-memory-model-823f02cef0bf
      3.https://www3.physnet.uni-hamburg.de/physnet/Tru64-Unix/HTML/APS33DTE/DOCU_005.HTM
      4.https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#page-locked-host-memory

      在Windows上可使用VirtualAlloc、VirtualLock、VirtualUnlock、VirtualFree函数进行内存锁定。

     以下为测试代码:

int test_memory_locking()
{
    constexpr size_t size{ 1024 };
#ifdef _MSC_VER
    // 1. allocate memory
    auto p = VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    if (p == nullptr) {
        std::cerr << "Error: VirtualAlloc: " << GetLastError() << "\n";
        return -1;
    }

    // 2. lock memory page
    if (!VirtualLock(p, size)) {
        std::cerr << "Error: VirtualLock: " << GetLastError() << "\n";
        return -1;
    }

    // 3. use lock memory

    // 4. unlock memory page
    if (!VirtualUnlock(p, size)) {
        std::cerr << "Error: VirtualUnlock: " << GetLastError() << "\n";
        return -1;
    }

    // 5. free memory
    if (!VirtualFree(p, 0, MEM_RELEASE)) {
        std::cerr << "Error: VirtualFree: " << GetLastError() << "\n";
        return -1;
    }
#else
    char data[size];

    // 1. get configuration information at run time
    auto page_size = sysconf(_SC_PAGE_SIZE);
    if (page_size == -1) {
        std::cerr << "Error: sysconf: " << strerror(errno) << "\n";
        return -1;
    }
    std::cout << "page size: " << page_size << "\n";

    // 2. lock memory page
    if (mlock(data, size) == -1) {
        std::cerr << "Error: mlock: " << strerror(errno) << "\n";
        return -1;
    }

    // 3. use lock memory

    // 4. unlock memory page
    if (munlock(data, size) == -1) {
        std::cerr << "Error: munlock: " << strerror(errno) << "\n";
        return -1;
    }
#endif

	return 0;
}

      执行结果如下图所示:

      GitHub:https://github.com/fengbingchun/Messy_Test

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

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

相关文章

二维码初体验 com.google.zxing 实现

文章目录 一、概述二、实现效果1. 完整版本2. 简化版本 三、源码结构四、完整代码 一、概述 Java 操作二维码的开源项目很多&#xff0c;如 SwetakeQRCode、BarCode4j、Zxing 等&#xff0c;这边以Zxing 为例进行介绍。 二、实现效果 1. 完整版本 选择需要生成QR原始文件&a…

大模型工具_awesome-chatgpt-prompts-zh

https://github.com/PlexPt/awesome-chatgpt-prompts-zh 1 功能 整体功能&#xff0c;想解决什么问题 ChatGPT 中文调教指南&#xff1a;提供一些常用的使用场景及对应的 Prompt 提示 当前解决了什么问题&#xff0c;哪些问题解决不了 针对想解决实际问题&#xff0c;但不知道…

图像识别中的 Vision Transformers (ViT)

引言 Vision Transformers (ViT) 最近已成为卷积神经网络(CNN) 的竞争替代品&#xff0c;而卷积神经网络 (CNN) 目前在不同的图像识别计算机视觉任务中处于最先进的水平。ViT 模型在计算效率和准确性方面比当前最先进的 (CNN) 模型高出近 4 倍。 Transformer 模型已成为自然语…

Diffusion扩散模型学习:图片高斯加噪

高斯分布即正态分布&#xff1b;图片高斯加噪即把图片矩阵每个值和一个高斯分布的矩阵上的对应值相加 1、高斯分布 np.random.normal 一维&#xff1a; import numpy as np import matplotlib.pyplot as pltdef generate_gaussian_noise(mean, std_dev, size):noise np.ran…

小白入门之安装NodeJS

重生之我在大四学JAVA 第五章 安装NodeJS 如果你在购买我闲鱼的程序&#xff0c;请尽量使用node14版本 修改安装路径 接着傻瓜式NEXT 测试是否安装成功 如果上面没提示版本号&#xff0c;就按照前两章配置环境变量步骤配置下环境变量 设置镜像地址 npm config set re…

一种简单的自编码器PyTorch代码实现

1. 引言 对于许多新接触深度学习爱好者来说&#xff0c;玩AutoEncoder总是很有趣的&#xff0c;因为它具有简单的处理逻辑、简易的网络架构&#xff0c;方便可视化潜在的特征空间。在本文中&#xff0c;我将从头开始介绍一个简单的AutoEncoder模型&#xff0c;以及一些可视化潜…

全渠道在线客服系统支持的沟通渠道:多渠道整合与无缝对接

我们在挑选客服系统的时候&#xff0c;经常会看到有些客服产品会强调自己是“全渠道客服系统”&#xff0c;那什么是全渠道客服系统呢&#xff1f; 1、什么是全渠道客服系统&#xff1f; 简单来讲&#xff0c;它是指能把某个客户在不同渠道的互动历史放到一起集中展现&#x…

rqt_graph使用说明

其中右边的&#xff1a;/rosout是一个topic 也就是一个话题 /rosout是一个topic 也是一个话题 可以看到凡是在rqt_graph里面用长方形标识的全都是话题 通过观察可以发现&#xff1a;凡是用椭圆标识的全都是节点 如果切换为Nodes only视图会发现&#xff1a; 所说的no…

SpringSecurity安全框架 ——认证与授权

目录 一、简介 1.1 什么是Spring Security 1.2 工作原理 1.3 为什么选择Spring Security 1.4 HttpSecurity 介绍&#x1f31f; 二、用户认证 2.1 导入依赖与配置 2.2 用户对象UserDetails 2.3 业务对象UserDetailsService 2.4 SecurityConfig配置 2.4.1 BCryptPasswo…

【数据结构入门精讲 | 第八篇】一文讲清全部排序算法(2)

在上一篇文章中我们介绍了冒泡排序、快速排序等算法&#xff0c;这一篇我们接着对排序算法的学习。 目录 归并排序堆排序选择排序计数排序基数排序排序总结 归并排序 归并排序是建立在归并操作上的一种有效&#xff0c;稳定的排序算法&#xff0c;该算法是采用分治法&#xff…

MySQL报错:1054 - Unknown column ‘xx‘ in ‘field list的解决方法

我在操作MySQL遇到1054报错&#xff0c;报错内容&#xff1a;1054 - Unknown column Cindy in field list&#xff0c;下面演示解决方法&#xff0c;非常简单。 根据箭头指示&#xff0c;Cindy对应的应该是VARCHAR文本数字类型&#xff0c;字符串要用引号&#xff0c;所以解决方…

【C语言】打印内存数据

C语言&#xff0c;用函数封装&#xff1a;16进制打印unsigned char *p指向的内存&#xff0c;长度为int l。16个字节&#xff0c;换一次行。16个字节用一个字符串缓存&#xff0c;一次打印。 以下是一个使用函数封装的C语言代码&#xff0c;用于以16进制格式打印unsigned char …

MySQL 事务的ACID特性

MySQL事务是什么&#xff0c;它就是一组数据库的操作&#xff0c;是访问数据库的程序单元&#xff0c;事务中可能包含一个或者多个 SQL 语句。这些SQL 语句要么都执行、要么都不执行。我们知道&#xff0c;在MySQL 中&#xff0c;有不同的存储引擎&#xff0c;有的存储引擎比如…

省时攻略:快速获得Creo安装包,释放创意天才!

不要再在网上浪费时间寻找Creo的安装包了&#xff0c;一键下载安装&#xff0c; 你要的一切都可以在这里找到&#xff01;我们深知在海量的信息中寻找合适的软件包并非易事&#xff0c;而且往往还伴随着繁琐的安装过程。然而&#xff0c;现在有了我们&#xff0c;一切变得轻松简…

【飞凌 OK113i-C 全志T113-i开发板】一些有用的常用的命令测试

一些有用的常用的命令测试 一、系统信息查询 可以查询板子的内核信息、CPU处理器信息、环境变量等 二、CPU频率 从上面的系统信息查询到&#xff0c;这是一颗具有两个ARMv7结构A7内核的处理器&#xff0c;主频最高1.2GHz 可以通过命令查看当前支持的频率以及目前所使用主频 …

爬虫工作量由小到大的思维转变---<第二十三章 Scrapy开始很快,越来越慢(医病篇)>

诊断篇https://blog.csdn.net/m0_56758840/article/details/135170994?ops_request_misc%257B%2522request%255Fid%2522%253A%2522170333243316800180644102%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id1703332433168001806441…

更改WiseAlign软件界面图标方法

更改WiseAlign软件界面图标方法 未替换时 首先将图片转换为BMP格式&#xff0c;在搜索栏处输入画图&#xff0c;点击打开画图工具 按住图标拖动到画布内&#xff0c;或是直接CtrlV将图标复制到画布内 点击文件&#xff0c;再点击另存为 保存类型选择“24位位图&#xff08;*.bm…

SpringBoot3-基础特性

文章目录 自定义 banner自定义 SpringApplicationFluentBuilder APIProfiles指定环境环境激活环境包含Profile 分组Profile 配置文件 外部化配置配置优先级 外部配置导入配置属性占位符 单元测试-JUnit5测试组件测试注解断言嵌套测试参数化测试 自定义 banner banner 就是启动…

MySQL数据库 触发器

目录 触发器概述 语法 案例 触发器概述 触发器是与表有关的数据库对象&#xff0c;指在insert/update/delete之前(BEFORE)或之后(AFTER)&#xff0c;触发并执行触发器中定义的soL语句集合。触发器的这种特性可以协助应用在数据库端确保数据的完整性&#xff0c;日志记录&am…

idea多光标无法取消

通常按住alt 鼠标左键。是多光标操作 但是不知道怎么按照了导致一直多光标 使用 altshiftinsert 取消多光标