当前位置: 首页 > news >正文

Intel oneAPI笔记(4)--jupyter官方文档(Unified Shared Memory)学习笔记

前言

本文是对jupyterlab中oneAPI_Essentials/03_Unified_Shared_Memory文档的学习记录,主要包含对统一共享内存的讲解

USM概述

USM (Unified Shared Memory)是SYCL中基于指针的内存管理。对于使用malloc或new来分配数据的C和C++程序员来说应该很熟悉。当将现有的C/ C++代码移植到SYCL时,USM简化了程序员的开发

使用USM,开发人员可以在主机和设备代码中引用相同的内存对象

Types of USM

统一共享内存为管理内存提供了显式和隐式模型

USM初始化:下面的初始化显示了使用malloc_shared共享分配的示例,“q”队列参数提供了有关内存可访问的设备的信息

下面是在host上分配内存的方法:

释放USM

数据隐式移动

下面的SYCL代码显示了使用malloc_shared的USM的实现,其中数据在主机和设备之间隐式地移动。可以用最少的代码快速获得功能,开发人员不必担心在主机和设备之间移动内存

#include <sycl/sycl.hpp>
using namespace sycl;static const int N = 16;int main() {queue q;std::cout << "Device : " << q.get_device().get_info<info::device::name>() << "\n";//# USM allocation using malloc_sharedint *data = malloc_shared<int>(N, q);//# Initialize data arrayfor (int i = 0; i < N; i++) data[i] = i;//# Modify data array on deviceq.parallel_for(range<1>(N), [=](id<1> i) { data[i] *= 2; }).wait();//# print outputfor (int i = 0; i < N; i++) std::cout << data[i] << "\n";free(data, q);return 0;
}

运行结果

数据显示移动

下面的SYCL代码显示了使用malloc_device的USM实现,其中主机和设备之间的数据移动应该由开发人员使用memcpy显式地完成

#include <sycl/sycl.hpp>
using namespace sycl;static const int N = 16;int main() {queue q;std::cout << "Device : " << q.get_device().get_info<info::device::name>() << "\n";//# initialize data on hostint *data = static_cast<int *>(malloc(N * sizeof(int)));for (int i = 0; i < N; i++) data[i] = i;//# Explicit USM allocation using malloc_deviceint *data_device = malloc_device<int>(N, q);//# copy mem from host to deviceq.memcpy(data_device, data, sizeof(int) * N).wait();//# update device memoryq.parallel_for(range<1>(N), [=](id<1> i) { data_device[i] *= 2; }).wait();//# copy mem from device to hostq.memcpy(data, data_device, sizeof(int) * N).wait();//# print outputfor (int i = 0; i < N; i++) std::cout << data[i] << "\n";free(data_device, q);free(data);return 0;
}

运行结果

代码解释

本代码让数据在主机区和设备区显示移动,提高了开发人员对数据的可控性

首先本代码使用malloc在主机分配内存,然后给这些内存赋值,然后使用malloc_device在设备区分配内存,然后把主机区的内存拷贝到设备区的这些内存中,然后在设备区加速处理这些数据之后再拷贝到主机区的原内存中,最后使用cout输出

USM的优势

SYCL*缓冲区功能强大且优雅,但是,在c++程序中用缓冲区替换所有指针和数组可能会给程序员带来负担,因此在这种情况下可以考虑使用USM

1.当把c++代码移植到sycl时,想要尽可能更改少的代码

2.当需要控制数据移动时,使用显式USM分配

3.在移植代码时使用共享分配可以快速获得功能

Data dependency in USM

程序员可以显式地使用wait对象,也可以使用命令组中的depends_on方法来指定在任务开始之前必须完成的事件列表

在下面的示例中,两个内核任务正在更新相同的数据数组,这两个内核可以同时执行,并且可能导致错误的结果

Different options to manage data dependency when using USM:

wait()

在内核任务上使用q.wait()来等待下一个依赖的任务可以开始,但是它会阻塞主机上的执行

in_order queue property

为队列使用in_order 队列属性,这将序列化所有内核任务。注意,即使队列没有数据依赖关系,执行也不会重叠

depends_on

在命令组中使用h.depends_on(e)方法来指定任务开始之前必须完成的事件

简化版

Code Example: USM and Data dependency

这个例子主要演示了上面三种方法的使用

初始代码

想要修改上面代码,只需下面三种方法三选一

使用wait

使用in_order queue property

使用depends_on

运行结果

Lab Exercise: Unified Shared Memory

实验要求

下面是我已经补全的代码和运行结果

#include <sycl/sycl.hpp>
#include <cmath>
using namespace sycl;
static const int N = 1024;
int main() {queue q;std::cout << "Device : " << q.get_device().get_info<info::device::name>() << "\n";//intialize 2 arrays on hostint *data1 = static_cast<int *>(malloc(N * sizeof(int)));int *data2 = static_cast<int *>(malloc(N * sizeof(int)));for (int i = 0; i < N; i++) {data1[i] = 25;data2[i] = 49;}//# STEP 1 : Create USM device allocation for data1 and data2//# YOUR CODE GOES HEREint *data_device1 = malloc_device<int>(N, q);int *data_device2 = malloc_device<int>(N, q);//# STEP 2 : Copy data1 and data2 to USM device allocation//# YOUR CODE GOES HERE  q.memcpy(data_device1, data1, sizeof(int) * N).wait();q.memcpy(data_device2, data2, sizeof(int) * N).wait();//# STEP 3 : Write kernel code to update data1 on device with sqrt of valueq.parallel_for(N, [=](auto i) { //# YOUR CODE GOES HERE data_device1[i] = (int)std::sqrt(float(data_device1[i]));}).wait();//# STEP 3 : Write kernel code to update data2 on device with sqrt of valueq.parallel_for(N, [=](auto i) { //# YOUR CODE GOES HERE data_device2[i] = (int)std::sqrt(float(data_device2[i]));}).wait();//# STEP 5 : Write kernel code to add data2 on device to data1q.parallel_for(N, [=](auto i) { //# YOUR CODE GOES HERE data_device1[i] += data_device2[i];}).wait();//# STEP 6 : Copy data1 on device to host//# YOUR CODE GOES HERE q.memcpy(data1, data_device1, sizeof(int) * N).wait();//# verify resultsint fail = 0;for (int i = 0; i < N; i++) if(data1[i] != 12) {fail = 1; break;}if(fail == 1) std::cout << " FAIL"; else std::cout << " PASS";std::cout << "\n";//# STEP 7 : Free USM device allocations//# YOUR CODE GOES HEREfree(data_device1, q);free(data_device2, q);free(data1);free(data2);//# STEP 8 : Add event based kernel dependency for the Steps 2 - 6return 0;
}

 运行结果

注:

 

这里可能转成double或者什么也不转都会报错,我电脑对这一块好像仅支持单精度,只能转成float才能运行,具体原理也不理解

http://www.lryc.cn/news/225894.html

相关文章:

  • dRep-基因组质控、去冗余及物种界定
  • 截图贴图软件推荐 - 附下载链接 | Snipaste | Steuna
  • python调用chrome实现网页自动操作
  • FFMPEG库实现mp4/flv文件(H264+AAC)的封装与分离
  • 《红蓝攻防对抗实战》九.内网穿透之利用GRE协议进行隧道穿透
  • 大数据毕业设计选题推荐-智慧消防大数据平台-Hadoop-Spark-Hive
  • LeetCode 面试题 16.20. T9键盘
  • systemctl enable docker.service报错“Failed to execute operation: Bad message“
  • 向量的范数、矩阵的范数
  • C# OpenCvSharp 玉米粒计数
  • 前端缓存机制——强缓存、弱缓存、启发式缓存
  • 对称密钥加密与非对称密钥加密:原理与应用
  • 商品小类管理实现B
  • Unity--视觉组件(Raw Image,Mask)||Unity--视觉组件(Text,Image)
  • 在Node.js中,什么是事件发射器(EventEmitter)?
  • STM32——NVIC中断优先级管理分析
  • YOLOV5----修改损失函数-SimAM
  • MongoDB单实例安装(windows)
  • Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
  • 安卓RadioButton设置图片大小
  • 电脑怎么录制视频,录制的视频怎么剪辑?
  • 外接式网络隔离变压器/网络隔离滤波器/网口变压器/脉冲变压器/网络隔离变压器模块
  • AI:83-基于深度学习的手势识别与实时控制
  • MySQL---存储过程
  • 宠物社区系统宠物领养小程序,宠物救助小程序系统多少钱?
  • d3.js
  • okhttp关于header修改
  • pytorch代码实现注意力机制之Flatten Attention
  • 激光雷达和人工智能
  • 【算法练习Day44】最长递增子序列最长连续递增序列最长重复子数组