---
title: 内存语义同步
description: "内存语义同步机制允许用户基于通用Device内存实现同步。与Event/Notify同步机制不同，基于内存语义的同步机制还支持算子作为同步参与方，即算子可以在执行过程中与另一条流进行同步。"
url: https://www.hiascend.com/document/detail/zh/canncommercial/latest/programug/acldevg/runtime_doc_dev_0028.html
sourcePath: /source/zh/canncommercial/900/programug/acldevg/runtime_doc_dev_0028.html
indexId: f44e03cde5734144418a81290c3cd578b422e8db52e9021923ef4bbf9e8ea78673
---
# 内存语义同步

内存语义同步机制允许用户基于通用Device内存实现同步。与Event/Notify同步机制不同，基于内存语义的同步机制还支持算子作为同步参与方，即算子可以在执行过程中与另一条流进行同步。

下图展示了在算子执行过程中与另一条流之间的同步过程：


内存语义同步相关接口的调用代码示例如下，不可以直接拷贝编译运行，仅供参考：

- Device示例代码（算子核函数实现代码）
  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 extern "C" __global__ __aicore__ void myKernel1(GM_ADDR syncMem) { // 算子逻辑 ...... // 向syncMem所指向内存写1 __gm__ uint64_t* flag = reinterpret_cast<__gm__ uint64_t*>(syncMem); *flag = 1; dcci(flag, 0, 2); // 算子逻辑 ...... } extern "C" __global__ __aicore__ void myKernel2(GM_ADDR syncMem) { // 算子逻辑 ... // 轮询阻塞直到syncMem所指向内存值为2 __gm__ volatile uint64_t* flag = reinterpret_cast<__gm__ uint64_t*>(syncMem); dcci(flag, 0, 2); while (*flag != 2) { dcci(flag, 0, 2); } // 算子逻辑 ...... }


- Host示例代码
  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 // 创建Stream aclrtStream stream1; aclrtStream stream2; aclrtCreateStream(&stream1); aclrtCreateStream(&stream2); // 申请Device内存 void* syncMem; aclrtMalloc(&syncMem, sizeof(uint64_t), ACL_MEM_MALLOC_NORMAL_ONLY); // 在stream1上下发wait任务，该任务阻塞等待直到syncMem所指向内存中的值为1 aclrtValueWait(syncMem, 1, ACL_STREAM_WAIT_VALUE_EQ, stream1); // 在stream2上下发myKernel1，该kernel内部向syncMem所指向内存写1，从而解除stream1上wait任务的阻塞状态 myKernel1<<<numBlocks, nullptr, stream2>>>(syncMem); // 在stream1上下发myKernel2，该kernel内部轮询等待直到syncMem所指向内存的值为2 myKernel2<<<numBlocks, nullptr, stream1>>>(syncMem); // 在stream2上下发write任务，该任务往syncMem所指向内存写为2，从而解除stream1上myKernel2的阻塞状态 aclrtValueWrite(syncMem, 2, 0, stream2);


说明：因为内存语义同步机制是基于通用Device内存实现，所以可以通过aclrtMemset/aclrtMemsetAsync初始化和清除同步所用的内存。
