news 2026/5/10 4:47:57

CANN Runtime进程间通信

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CANN Runtime进程间通信

# 进程间通信

【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime

由某个主机线程创建的任意设备内存、Event资源或Notify资源,都可以在同一进程内被该进程中的其他线程直接引用。但这些指针或句柄在进程之外是无效的,因此不能被其他进程的线程直接使用。

若要在不同进程之间共享设备内存、Event资源或Notify资源,需要应用程序使用Runtime提供的进程间通信相关API以实现如下典型场景:由一个主进程生成一批输入数据,并将这些数据提供给多个从属进程使用,而无需在每个进程中重新生成或复制数据。不同资源涉及的IPC(Inter-Process Communication)接口不同,可查看下文中的调用示例。

需要注意的是,通过aclrtMalloc接口分配设备内存时,出于性能考虑,可能会从更大的底层内存块中切分出来。在这种情况下,IPC接口会检查共享内存是否页表对齐,若未对齐,API将拦截并报错,以防止跨进程多映射内存导致的信息泄露风险。因此,建议使用aclrtMalloc接口根据内存分配规则申请内存。申请不同类型的内存时,其页表大小会有所不同:普通页内存的页表大小为4K,大页内存的页表大小支持2M或1G。

进程间共享内存

此处以A进程(内存出借方)、B进程(内存借入方)为例,说明两个进程间的内存共享接口调用流程:

以下为A、B进程之间共享内存的示例代码,不可以直接拷贝编译运行,仅供参考。完整样例代码请参见Link。

  1. 在A进程中分配内存,生成共享key:

    uint keyLen = 65; char[keyLen] key; void *ptrA = nullptr; aclrtSetDevice(0); // 进程A使用Device 0 aclrtMalloc(&ptrA, size); aclrtIpcMemGetExportKey(ptrA, size, key, keyLen, ACL_RT_IPC_MEM_EXPORT_FLAG_DISABLE_PID_VALIDATION); // 跨进程通信交换key(以写文件方式交互) writeFile("file/ipc_mem", key, keyLen); // 对共享内存进行读写操作 ...... // 待共享内存使用完成后,借出方关闭IPC共享内存 aclrtIpcMemClose(key); aclrtFree(ptrA); aclrtResetDeviceForce(0);
  2. 在B进程中,通过共享key导入共享内存:

    uint keyLen = 65; char[keyLen] key; void *ptrB; // 跨进程通信交换key(以写文件方式交互) readFile("file/ipc_mem", key, keyLen); aclrtSetDevice(1); // 进程B使用Device 1 // A,B进程使用不同的Device,导入共享内存访问要开启两个Device之间的数据交互 aclrtIpcMemImportByKey(&ptrB, key, ACL_RT_IPC_MEM_IMPORT_FLAG_ENABLE_PEER_ACCESS); // 对ptrB内存读写操作 ...... // 使用完成后,借入方关闭IPC共享内存 aclrtIpcMemClose(key); aclrtResetDeviceForce(1);

进程间共享Event

进程之间通过共享Event,可以实现进程间的事件同步。此处以A进程创建Event,共享给B进程为例,说明两个进程间任务同步的示例代码,不可以直接拷贝编译运行,仅供参考。

  1. 在A进程中创建Event,生成共享handle:

    aclrtEvent event; aclrtStream stream; aclrtIpcEventHandle handle; aclrtSetDevice(0); // 进程A使用Device 0 aclrtCreateEventExWithFlag(&event, ACL_EVENT_IPC); // 创建IPC Event aclrtCreateStream(&stream); // 创建Stream // 导出进程间共享handle aclrtIpcGetEventHandle(event, &handle); // 跨进程通信交换key(以写文件方式交互) writeFile("file/ipc_event", handle, ACL_IPC_EVENT_HANDLE_SIZE); // 下发record任务 aclrtEventRecord(event, stream); // Event使用完, 销毁共享Event aclrtDestroyEvent(event); aclrtResetDeviceForce(0);
  2. 在B进程中,通过共享handle导入共享Event:

    aclrtStream stream; aclrtEvent event; aclrtIpcEventHandle handle; aclrtCreateStream(&stream); // 创建Stream // 跨进程获取共享handle(以写文件方式交互) readFile("file/ipc_event", handle, ACL_IPC_EVENT_HANDLE_SIZE); aclrtSetDevice(1); //进程B使用Device 1 // 导入handle,返回共享event // A,B进程使用不同的Device aclrtIpcOpenEventHandle(handle, &event); // 下发wait任务 aclrtStreamWaitEvent(stream, event); // 同步Stream上的任务 aclrtSynchonizeStream(stream); // Event使用完,销毁共享Event aclrtDestroyEvent(event); aclrtResetDeviceForce(1);

进程间共享Notify

进程之间通过共享Notify,可以实现进程间的通知。此处以A进程创建Notify,共享给B进程为例,说明两个进程间任务同步的示例代码,不可以直接拷贝编译运行,仅供参考。完整样例代码请参见Link。

注意:创建端会分配Notify硬件资源,因此只能由创建端硬件进行Wait。为此共享Notify有使用约束,只能在创建端调aclrtNotifyWait进行Wait,不能在共享端Wait。

  1. 在A进程中创建Notify,生成共享key:

    uint keyLen = 65; char key[keyLen]; aclrtNotify notify; aclrtStream stream; // 进程A使用Device 0 aclrtSetDevice(0); aclrtCreateStream(&stream); aclrtNotifyCreate(&notify); // 导出key(即Notify共享名称) aclrtNotifyGetExportKey(notify, key, keyLen, ACL_RT_NOTIFY_EXPORT_FLAG_DISABLE_PID_VALIDATION); // 跨进程通信交换key(以写文件方式交互) writeFile("file/ipc_notify", key, keyLen); // 下发wait任务 aclrtNotifyWait(notify, stream); // Notify使用完, 销毁共享Notify aclrtNotifyDestroy(notify); aclrtResetDeviceForce(0);
  2. 在B进程中,通过共享key导入共享Notify:

    uint keyLen = 65; char key[keyLen]; aclrtNotify notify; aclrtStream stream; // 跨进程通信交换key(以写文件方式交互) readFile("file/ipc_notify", key, keyLen); //进程B使用Device 1 aclrtSetDevice(1); aclrtCreateStream(&stream); // 导入key,返回共享Notify // A,B进程使用不同的Device,导入共享Notify要开启两个Device之间的数据交互 aclrtNotifyImportByKey(&notify, key, ACL_RT_NOTIFY_IMPORT_FLAG_ENABLE_PEER_ACCESS); // 下发record任务 aclrtNotifyRecord (notify, stream); // Notify使用完,销毁共享Notify aclrtNotifyDestroy(notify); aclrtResetDeviceForce(1);

通过VMM接口实现进程间共享内存

除IPC Mem共享内存外,Runtime还提供了另外一套内存管理和内存共享接口。VMM(Virtual Memory Management)这套接口提供更灵活的功能,支持虚拟地址申请、物理内存申请和跨进程物理内存共享,还支持虚拟地址与物理内存之间的映射操作。

此处以A、B进程为例,说明一个Device上、两个进程间的物理内存共享的示例代码,不可以直接拷贝编译运行,仅供参考,完整样例代码请参见Link。

若A、B进程使用不同的Device,还需配合使用aclrtDeviceEnablePeerAccess接口开启跨Device的数据交互,详细描述请参见跨Device的数据交互。

  1. 在A进程中:

    // 查询内存申请粒度 const size_t dataSize = 1024 * sizeof(float); aclrtPhysicalMemProp prop = {}; prop.handleType = ACL_MEM_HANDLE_TYPE_NONE; prop.allocationType = ACL_MEM_ALLOCATION_TYPE_PINNED; prop.location.type = ACL_MEM_LOCATION_TYPE_DEVICE; prop.location.id = 0; prop.memAttr = ACL_HBM_MEM_NORMAL; size_t granularity = 0UL; aclrtMemGetAllocationGranularity(&prop, ACL_RT_MEM_ALLOC_GRANULARITY_MINIMUM, &granularity); // 基于内存申请粒度申请物理内存 size_t alignedSize = ((dataSize + granularity - 1U) / granularity) * granularity; aclrtDrvMemHandle handle = nullptr; aclrtMallocPhysical(&handle, alignedSize, &prop, 0); // 预留虚拟内存 void *virPtr; aclrtReserveMemAddress(&virPtr, alignedSize, 0, nullptr, 0); // 将虚拟内存映射到物理内存 aclrtMapMem(virPtr, alignedSize, 0, handle, 0); aclrtMemAccessDesc desc = {}; desc.flags = ACL_RT_MEM_ACCESS_FLAGS_READWRITE; desc.location.id = 0; desc.location.type = ACL_MEM_LOCATION_TYPE_DEVICE; aclrtMemSetAccess(virPtr, alignedSize, &desc, 1); // 使用virPtr进行复制、读、写等操作 ...... // 导入共享handle uint64_t shareableHandle = 0ULL; aclrtMemExportToShareableHandle(handle, ACL_MEM_HANDLE_TYPE_NONE, ACL_RT_VMM_EXPORT_FLAG_DISABLE_PID_VALIDATION , &shareableHandle); // 将共享handle传递给进程B writeFile("file/vmm_mem", shareableHandle, sizeof(shareableHandle)); // 取消虚拟内存与物理内存之间的映射关系 aclrtUnmapMem(virPtr); // 释放虚拟内存和物理内存 aclrtReleaseMemAddress(virPtr); aclrtFreePhysical(handle);
  2. 在B进程中:

    uint64_t shareableHandle = 0ULL; // 从文件中获取共享handle readFile("file/vmm_mem", &shareableHandle, sizeof(shareableHandle)); aclrtDrvMemHandle handle = nullptr; int32_t deviceId=0; aclrtMemImportFromShareableHandle(shareableHandle, deviceId, &handle); // 查询内存申请粒度 const size_t data_size = 1024 * sizeof(float); aclrtPhysicalMemProp prop = {}; prop.handleType = ACL_MEM_HANDLE_TYPE_NONE; prop.allocationType = ACL_MEM_ALLOCATION_TYPE_PINNED; prop.location.type = ACL_MEM_LOCATION_TYPE_DEVICE; prop.location.id = 0; prop.memAttr = ACL_HBM_MEM_NORMAL; size_t granularity = 0UL; aclrtMemGetAllocationGranularity(&prop, ACL_RT_MEM_ALLOC_GRANULARITY_MINIMUM, &granularity); size_t alignedSize = ((dataSize + granularity - 1U) / granularity) * granularity; // 基于内存申请粒度预留虚拟内存 void *virPtr = nullptr; aclrtReserveMemAddress(&virPtr, alignedSize, 0, nullptr, 0); // 将虚拟内存映射到物理内存 aclrtMapMem(virPtr, alignedSize, 0, handle, 0); aclrtMemAccessDesc desc = {}; desc.flags = ACL_RT_MEM_ACCESS_FLAGS_READWRITE; desc.location.id = 0; desc.location.type = ACL_MEM_LOCATION_TYPE_DEVICE; aclrtMemSetAccess(virPtr,alignedSize, &desc, 1); // 使用virPtr进行复制、读、写等操作 ...... // 取消虚拟内存与物理内存之间的映射关系 aclrtUnmapMem(virPtr); // 释放虚拟内存和物理内存 aclrtReleaseMemAddress(virPtr); aclrtFreePhysical(handle);

【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/10 4:46:29

qclaw-wechat-client:微信API集成客户端的设计、部署与高级应用

1. 项目概述:一个面向开发者的微信生态集成客户端 如果你是一名开发者,尤其是在国内做小程序、公众号或者企业微信相关业务,那么“如何高效、稳定地调用微信API”这个问题,大概率是你日常开发中的痛点之一。官方SDK虽然权威&…

作者头像 李华
网站建设 2026/5/10 4:46:27

大规模任务调度优化:OpenClaw 高并发批量任务的队列管理、失败重试、断点续传实操方案

大规模任务调度优化:OpenClaw 高并发批量任务的队列管理、失败重试、断点续传实操方案引言在当今的数据驱动时代,处理海量数据、执行大规模批量任务已成为众多业务场景的常态。无论是电商平台的订单处理、金融系统的交易清算、日志分析、还是AI模型的分布…

作者头像 李华
网站建设 2026/5/10 4:45:35

056、步进电机加减速曲线:梯形曲线

步进电机加减速曲线:梯形曲线 从一次丢步事故说起 去年做一台三轴点胶机,Z轴用57步进电机带丝杆,升降频率设成固定2000Hz。客户反馈点胶到第37个点的时候,针头突然扎歪,胶水涂到PCB板外面去了。我连夜赶去现场,用示波器抓驱动器的STEP脉冲——好家伙,电机在启动瞬间脉…

作者头像 李华
网站建设 2026/5/10 4:42:31

AI对话管理利器:一键导出ChatGPT等对话为Markdown/JSON

1. 项目概述:一个浏览器脚本,如何成为我的AI对话管理利器 如果你和我一样,日常重度依赖ChatGPT、Claude、Gemini这些AI助手来辅助工作、学习或头脑风暴,那你一定遇到过这个痛点:那些充满灵光一闪的对话、精心设计的提…

作者头像 李华
网站建设 2026/5/10 4:41:33

KnowLM开源框架:知识增强大模型在信息抽取与对话中的实践指南

1. 项目概述:一个为知识而生的开源大语言模型框架 如果你正在寻找一个能够处理中文和英文、专注于知识增强与信息抽取、并且提供从数据处理到模型部署完整流程的开源大语言模型框架,那么 zjunlp/KnowLM 绝对值得你花时间深入了解。这不是一个简单的模…

作者头像 李华
网站建设 2026/5/10 4:40:43

基于AWS Bedrock与OpenSearch构建企业级RAG智能问答系统

1. 项目概述:构建基于企业知识库的智能问答系统最近在帮一个团队做技术选型,他们手头有一堆产品手册、技术文档和内部会议纪要,想快速搭建一个能“理解”这些资料并回答员工问题的智能助手。这其实就是典型的RAG(检索增强生成&…

作者头像 李华