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

news2024/12/23 14:03:59

前言

本文是对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_shared
  int *data = malloc_shared<int>(N, q);

  //# Initialize data array
  for (int i = 0; i < N; i++) data[i] = i;

  //# Modify data array on device
  q.parallel_for(range<1>(N), [=](id<1> i) { data[i] *= 2; }).wait();

  //# print output
  for (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 host
  int *data = static_cast<int *>(malloc(N * sizeof(int)));
  for (int i = 0; i < N; i++) data[i] = i;

  //# Explicit USM allocation using malloc_device
  int *data_device = malloc_device<int>(N, q);

  //# copy mem from host to device
  q.memcpy(data_device, data, sizeof(int) * N).wait();

  //# update device memory
  q.parallel_for(range<1>(N), [=](id<1> i) { data_device[i] *= 2; }).wait();

  //# copy mem from device to host
  q.memcpy(data, data_device, sizeof(int) * N).wait();

  //# print output
  for (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 host
  int *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 HERE
  int *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 value
  q.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 value
  q.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 data1
  q.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 results
  int 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 HERE
  free(data_device1, q);
  free(data_device2, q);
  free(data1);
  free(data2);
  //# STEP 8 : Add event based kernel dependency for the Steps 2 - 6
  return 0;
}

 运行结果

注:

 

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

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

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

相关文章

如何定义类

类是将数据和方法封装在一起的一种数据结构&#xff0c;其中数据表示类的属性&#xff0c;方法表示类的行为&#xff0c;所以定义类实际上就是定义类的属性与方法。用户定义一个类实际上就是定义一个新的数据类型。在使用类之前&#xff0c;必须先定义它&#xff0c;然后才可利…

【JavaEE初阶】 UDP协议的详细解析

文章目录 &#x1f332;UDP协议概念&#x1f334;UDP协议端格式&#x1f384;UDP的特点&#x1f6a9;无连接&#x1f6a9;不可靠传输&#x1f6a9;面向数据报&#x1f6a9;缓冲区&#x1f6a9;全双工&#x1f6a9;大小受限 &#x1f340;基于UDP的应用层协议&#x1f38d;扩展问…

Linux安装nodejs问题

安装nodejs后&#xff0c;使用node -v报下图 参考下面两个可解决&#xff1a;【Linux-编译器gcc/glibc升级】CentOS7.9使用NodeJS18时报错/lib64/libm.so.6: version GLIBC_2.27‘ not found-CSDN博客 报错信息ImportError: /lib64/libstdc.so.6: version CXXABI_1.3.9‘ not f…

JavaScript使用对象

对象(object)是最基本、最通用的类型&#xff0c;具有复合性结构&#xff0c;属于引用型数据&#xff0c;对象的结构具有弹性&#xff0c;内部的数据是无序的&#xff0c;每个成员被称为属性。在JavaScript中&#xff0c;对象是一个泛化的概念&#xff0c;任何值都可以转换为对…

FreeRTOS源码阅读笔记2--list.c

list.c中主要完成列表数据结构的操作&#xff0c;有列表和列表项的初始化、列表的插入和移除。 2.1列表初始化vListInitialise() 2.1.1函数原型 void vListInitialise( List_t * const pxList ) pxList&#xff1a;列表指针&#xff0c;指向要初始化的列表。 2.1.2函数框架…

viple进阶2:打印九九乘法表

&#xff08;1&#xff09;题目 题目&#xff1a;使用viple打印九九乘法表 &#xff08;2&#xff09;设计与实现 观察效果图&#xff0c;发现&#xff1a; 1、第1行&#xff0c;有1个公式&#xff1b;第2行有2个公式&#xff1b;第3行有3个公式&#xff0c;以此类推&#x…

Texlive安装

下载4.8G的iso文件 解压 或 装载后&#xff0c;以管理员身份运行(.bat)文件。 运行以下两句代码进行Texlive相关升级 tlmgr option repository otan tlmgr update --self --all 运行以下三行代码&#xff0c;检查是否安装成功 latex -v xelatex -v pdflatex -v 如果有异常…

基于协作搜索算法的无人机航迹规划-附代码

基于协作搜索算法的无人机航迹规划 文章目录 基于协作搜索算法的无人机航迹规划1.协作搜索搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用协作搜索算法来优化无人机航迹规划。 …

思谋科技进博首秀:工业多模态大模型IndustryGPT V1.0正式发布

大模型技术正在引领新一轮工业革命&#xff0c;但将其应用于工业制造&#xff0c;仍面临许多挑战&#xff0c;专业知识的缺乏是关键难点。11月5日&#xff0c;香港中文大学终身教授、思谋科技创始人兼董事长贾佳亚受邀参加第六届中国国际进口博览会暨虹桥国际经济论坛开幕式。虹…

技术分享 | app自动化测试(Android)--显式等待机制

WebDriverWait类解析 WebDriverWait 用法代码 Python 版本 WebDriverWait( driver,timeout,poll_frequency0.5,ignored_exceptionsNone) 参数解析&#xff1a; driver&#xff1a;WebDriver 实例对象 timeout: 最长等待时间&#xff0c;单位秒 poll_frequency: 检测的间…

技术分享 | Appium 用例录制

下载及安装 下载地址&#xff1a; github.com/appium/appi… 下载对应系统的 Appium 版本&#xff0c;安装完成之后&#xff0c;点击 “Start Server”&#xff0c;就启动了 Appium Server。 在启动成功页面点击右上角的放大镜&#xff0c;进入到创建 Session 页面。配置好…

nginx-配置拆分(各个模块详细说明)

主配置文件 配置结构 ... #nginx全局块events { #events块... #events块 }http { #http块... #http全局块server { #server块... #server全局块location [PATTERN] { #location块... #location块}location [PATTERN] {...}}serv…

2023年起重机司机(限桥式起重机)证考试题库及起重机司机(限桥式起重机)试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年起重机司机(限桥式起重机)证考试题库及起重机司机(限桥式起重机)试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作…

算法打卡01——求两数之和

题目&#xff1a; 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你…

TCP/IP的基础知识

文章目录 TCP/IP的基础知识硬件&#xff08;物理层&#xff09;网络接口层&#xff08;数据链路层&#xff09;互联网层&#xff08;网络层&#xff09;TCP/IP的具体含义传输层应用层&#xff08;会话层以上的分层&#xff09;TCP/IP分层模型与通信示例发送数据包的一个例子接收…

Notepad++中删除连续的任意n行

使用Notepad里的行标记功能&#xff0c;可以删除指定的任意n行。 案例1&#xff0c;删除sample2.dat里的第201行到第10000行。方法如下&#xff1a; (1) 用户NotePad打开sample2.dat&#xff0c;右击201行 —》“开始/结束”/开始 图(1) 选择行的起点&#xff1a;201 (2) 接…

计算机网络第4章-通用转发和SDN

引子&#xff1a; 在前面&#xff0c;我们将基于目的地转发的特征总结为两个步骤&#xff1a; 查找目的IP地址&#xff08;匹配&#xff09;&#xff0c;然后将分组发送到有特定输出端口的交换结构&#xff08;“动作”&#xff09;。 但是这种转发特征会带来许多问题&#…

Codeforces Round 907 (Div. 2——ABC)

A.Sorting with Twos 题目 给定一个数组a&#xff0c;可执行操作如下&#xff1a; 1、选择一个非负整数m&#xff0c;要求 2、将数组中元素从1到m减去1 问&#xff0c;是否可以通过以上操作得到一个单调不增的数组序列。 输入 首行样例个数t&#xff0c; 每个样例首行数…

MySQL第七讲·怎么利用聚合函数实现高效地分组统计?

你好&#xff0c;我是安然无虞。 文章目录 聚合函数&#xff1a;怎么高效地进行分组统计&#xff1f;sum( )avg( ) & max( ) & min( )count( ) 聚合函数&#xff1a;怎么高效地进行分组统计&#xff1f; MySQL中有5种聚合函数较为常用&#xff0c;分别是求和函数sum(…

面试官:说说Redis的SDS底层实现原理

文章目录 前言面试开始1、说说Redis基本类型有哪些2、String类型常用于什么场景3、String类型采用什么数据结构4、继续深入讲讲SDS实现细节5、你说说SDS和C语言字符串的区别5.1、SDS获取长度时间复杂度更低5.2、SDS杜绝缓冲区溢出5.3、SDS减少字符串内存重分配次数5.4、SDS二进…