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

Metal入门学习:GPU并行计算大数组相加

一、编程指南PDF下载链接(中英文档)
  • 1、Metal编程指南PDF链接
    https://github.com/dennie-lee/ios_tech_record/raw/main/Metal学习PDF/Metal 编程指南.pdf

  • 2、Metal着色语言(Metal Shader Language:简称MSL)编程指南PDF链接
    https://github.com/dennie-lee/ios_tech_record/raw/main/Metal学习PDF/Metal 着色语言指南.pdf

  • 3、补充:官网API文档链接
    https://developer.apple.com/documentation/metal/performing_calculations_on_a_gpu

二、内容前述

本文章通过元素个数相同的两个数组对应位置相加来切入Metal(GPU)的并行计算着色函数(本篇文章未涉及渲染函数:顶点着色函数和片元着色函数,会另起一篇文章介绍)。在此示例中,可以了解所有 Metal 应用程序中使用的基本任务。 您将看到如何将用 C 编写的简单函数转换为Metal着色语言 (Metal Shader Language :MSL),以便它可以在 GPU 上运行。通过创建管道,准备MSL函数在其上运行,并创建GPU可访问的数据对象。要针对您的数据执行管道,创建命令缓冲区,将命令写入其中,然后将缓冲区提交到命令队列,Metal将命令发送到GPU执行。
(下图是官网并行计算着色函数流程原理图:)
在这里插入图片描述

三、C语言和MSL语言对两个数组相加的函数对比
  • 1、C语言函数:两个数组相加
void add_arrays(const float* inA,const float* inB,float* result,int length){for (int index = 0; index < length ; index++){result[index] = inA[index] + inB[index];}
}
  • 2、MSL语言函数:两个数组相加
kernel void add_arrays(device const float* inA,device const float* inB,device float* result,uint index [[thread_position_in_grid]]){result[index] = inA[index] + inB[index];
}

关键词解释说明(在MSL编程指南PDF中可查看,点击上面的链接下载即可)
在这里插入图片描述
[[thread_position_in_grid]]文档中也有,更加详细的解析说明可查看这篇文章:https://juejin.cn/post/7085633906501746724,文章中还有延伸说明解释[[threadgroup_position_in_grid]]和[[threads_per_threadgroup]]

四、关键代码段解析
  • 1、初始化、加载扩展名为.metal的文件、创建管道状态对象加载并行计算着色函数
//_mDevice = MTLCreateSystemDefaultDevice();
// Load the shader files with a .metal file extension in the project
id<MTLLibrary> newDefaultLibrary = [_mDevice newDefaultLibrary];
if (newDefaultLibrary == nil){NSLog(@"Failed to find the default library");return nil;
}id<MTLFunction> newFunction = [newDefaultLibrary newFunctionWithName:@"add_arrays"];
if (newFunction == nil){NSLog(@"Failed to find the adder function");return nil;
}NSError *error;
// Create a compute pipeline state object.
//根据扩展名为.metal文件中kernel定义的函数创建计算管道(项目Add文件)
_mAddFunctionPSO = [_mDevice newComputePipelineStateWithFunction:newFunction error:&error];
if (_mAddFunctionPSO == nil){//  If the Metal API validation is enabled, you can find out more information about what//  went wrong.  (Metal API validation is enabled by default when a debug build is run//  from Xcode)NSLog(@"Failed to create pipeline state object,error : %@)",error);return nil;
}// 指令队列
_mCommandQueue = [_mDevice newCommandQueue];
if (_mCommandQueue == nil){NSLog(@"Failed to find command queue");return nil;
}
  • 2、初始化数组数据
//初始化数组数据
- (void)prepareData{_mBufferA = [_mDevice newBufferWithLength:bufferSize options:MTLResourceStorageModeShared];_mBufferB = [_mDevice newBufferWithLength:bufferSize options:MTLResourceStorageModeShared];_mBufferResult = [_mDevice newBufferWithLength:bufferSize options:MTLResourceStorageModeShared];[self generateRandomFloatData:_mBufferA];[self generateRandomFloatData:_mBufferB];
}- (void)generateRandomFloatData:(id<MTLBuffer>)buffer{float *dataPtr = buffer.contents;for (int index = 0; index < arrayLength; index++){dataPtr[index] = (float)rand() / (float)RAND_MAX;}
}
  • 3、指令参数添加,提交GPU计算
- (void)sendComputeCommand{//create a command buffer to hold commands//创建指令缓存冲区id<MTLCommandBuffer> commandBuffer = [_mCommandQueue commandBuffer];assert(commandBuffer != nil);//开始进行指令添加参数id<MTLComputeCommandEncoder> computeEncoder = [commandBuffer computeCommandEncoder];assert(computeEncoder != nil);NSTimeInterval startTimeInterval = [[[NSDate alloc] init] timeIntervalSince1970];[self encodeAdderCommand:computeEncoder];//添加参数完毕,[computeEncoder endEncoding];//提交执行指令[commandBuffer commit];//等待计算完毕[commandBuffer waitUntilCompleted];NSTimeInterval endTimeInterval = [[[NSDate alloc] init] timeIntervalSince1970];NSLog(@"长度为:%u 的两个数组相加(Metal方式)花费的时间:%f",arrayLength,(endTimeInterval - startTimeInterval));//验证计算结果[self verifyResults];
}- (void)encodeAdderCommand:(id<MTLComputeCommandEncoder>)computeEncoder{//encode pipeline state object and its parameters[computeEncoder setComputePipelineState:_mAddFunctionPSO];//此处的atIndex为0,与MSL函数中参数对应顺序对应(也可以设置buffer(0),此处可先忽略buffer,详细信息可查看着色语言编程指南PDF)[computeEncoder setBuffer:_mBufferA offset:0 atIndex:0];//此处的atIndex为1,与MSL函数中参数对应顺序对应(也可以设置buffer(1),此处可先忽略buffer,详细信息可查看着色语言编程指南PDF)[computeEncoder setBuffer:_mBufferB offset:0 atIndex:1];//此处的atIndex为1,与MSL函数中参数对应顺序对应(也可以设置buffer(2),此处可先忽略buffer,详细信息可查看着色语言编程指南PDF)[computeEncoder setBuffer:_mBufferResult offset:0 atIndex:2];//全部线程数量,此处对应[[thread_position_in_grid]],理解此处请看第三.2对应关键词解释的文章MTLSize gridSize = MTLSizeMake(arrayLength, 1, 1);NSUInteger threadGroupSize = _mAddFunctionPSO.maxTotalThreadsPerThreadgroup;if (threadGroupSize > arrayLength){threadGroupSize = arrayLength;}//线程组大小MTLSize threadGroupsize = MTLSizeMake(threadGroupSize, 1, 1);[computeEncoder dispatchThreads:gridSize threadsPerThreadgroup:threadGroupsize];
}
五、完整代码

例子:github链接:https://github.com/dennie-lee/MetalArrayAddDemo

相关文章:

Metal入门学习:GPU并行计算大数组相加

一、编程指南PDF下载链接(中英文档&#xff09; 1、Metal编程指南PDF链接 https://github.com/dennie-lee/ios_tech_record/raw/main/Metal学习PDF/Metal 编程指南.pdf 2、Metal着色语言(Metal Shader Language:简称MSL)编程指南PDF链接 https://github.com/dennie-lee/ios_te…...

关于在spyder,jupyter notebook下创建虚拟环境(pytorch,tensorflow)均有效

anaconda下载地址 https://www.anaconda.com/download/ 下载完成后打开anaconda目录下的 anaconda prompt 在命令行中输入下面的命令创建一个叫tf2.0的虚拟环境&#xff08;“tf2.0”是建立的Conda虚拟环境的名字&#xff0c;可以自拟&#xff09; conda create -n tf2.0 p…...

oracle 闪回恢复

oracle 闪回恢复 闪回恢复区主要通过3个初始化参数来设置和管理&#xff1a; db_recovery_file_dest&#xff1a;指定闪回恢复区的位置 db_recovery_file_dest_size&#xff1a;指定闪回恢复区的可用空间大小 db_flashback_retention_target&#xff1a;指定数据库可以回退的时…...

LeetCode 322 零钱兑换

题目&#xff1a; 给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount &#xff0c;表示总金额。计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额&#xff0c;返回 -1 。你可以认为每种硬币的数量…...

面试篇SpringMVC是什么以及工作原理

1&#xff0c;什么是SpringMVC呢&#xff1f; 它是Spring的一种设计模式&#xff0c;一款框架。 2&#xff0c;MVC分别代表什么&#xff1f; M代表模型即model的缩写&#xff0c;指业务逻辑层模型。V代表视图即View的缩写&#xff0c;指视图层。C则是controller的缩写&#xff…...

jQuery-层级选择器

<!DOCTYPE HTML> <html> <head> <meta http-equiv"Content-Type" content"text/html; charsetUTF-8"> <title>层级选择器</title> <style type"text/css"> …...

【Java数据结构】——第十节(下).选择排序与堆排序

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;Java初阶数据结构 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01; 文章目…...

45道SQL题目陆续更新

文章目录 学习视频配置环境第一天内连接 外连接第二天第三天 学习视频 学习视频 配置环境 四张表 配置四张表的sql语句 #创建发据库 create database frogdata charsetutf8&#xff1b;use frogdata;# 学生表 Student create table Student( SId varchar(10), Sname var…...

在线PS软件有哪些不错的推荐

许多新的UI设计合作伙伴非常关心在线ps工具的选择。现在市场上有各种各样的ps网页替代工具&#xff0c;数量众多&#xff0c;令人眼花缭乱。本文简要介绍了10个在线PS工具&#xff0c;我相信一定有一个适合你&#xff01; 1.即时设计 即时设计是一款在线 UI 设计工具&#xf…...

Java实现天气预报功能

如果要实现类似百度天气、手机App这样的天气预报功能该如何实现&#xff1f;首先想到的是百度... 背景&#xff1a; 最近公司做了一个项目&#xff0c;天气预报的功能也做上去了&#xff0c;不仅有实时天气、未来7天预报的功能、还有气象预警的功能。 天气包括基本天气、白天夜…...

python循环语句

while循环 Python中&#xff0c;while循环只要在条件&#xff08;表达式&#xff09;为真的情况下&#xff0c;就会一直重复执行相应的循环代码块。 while语句的语法格式如下&#xff1a; while 条件表达式&#xff1a;代码块while语句执行的具体流程为&#xff1a;首先判断…...

多线程基础(一)线程基础信息、synchronized 锁概念

1. 基本概念&#xff1a; 程序&#xff1a; 程序是一些保存在磁盘上的指令的有序集合&#xff0c;是静态的。程序包括&#xff1a;内存资源、IO资源、信号处理等。&#xff08;如&#xff1a;XX.exe&#xff09; 进程&#xff1a; 进程是程序执行的过程&#xff0c;包括了动态…...

JAVA期末考内容知识点的梳理

作者的话 前言&#xff1a;这些都是很基本的&#xff0c;还有很多没有写出来&#xff0c;重点在于考试复习&#xff0c;包括后四章的内容 前面内容请参考JAVA阶段考内容知识点的梳理 一、集合、流 课堂总结1集合 集合概念&#xff1a; 保存和盛装数据的容器&#xff0c;将许多…...

为什么要使用Thrift与Protocol Buffers?

编码数据的格式 程序通常&#xff08;至少&#xff09;使用两种形式的数据&#xff1a; 在内存中&#xff0c;数据保存在对象、结构体、列表、数组、散列表、树等中。 这些数据结构针对 CPU 的高效访问和操作进行了优化&#xff08;通常使用指针&#xff09;。如果要将数据写…...

oa是什么意思?oa系统哪个好用?

一、oa是什么意思 oa&#xff08;Office Automation办公自动化&#xff09;是一种将智能化科技应用于企业管理中的应用系统。它可以通过电脑网络、互联网等技术手段&#xff0c;将企业的各种业务流程、各种业务数据进行集成和处理&#xff0c;将各种业务流程和各种业务数据统一…...

Linq和C# Lambda表达式

什么是Linq 简介 Linq (Language Integrated Query) 是一种语言集成的查询技术&#xff0c;可以在C#和其他.NET语言中使用。Linq允许我们使用一种类SQL的语言来查询数据&#xff0c;这使得代码更加简洁和易于阅读。Linq提供了一种通用的查询接口&#xff0c;可以用于查询各种…...

蓝桥:前端开发笔面必刷题——Day2 数组(三)

文章目录 &#x1f4cb;前言&#x1f3af;两数之和 II&#x1f4da;题目内容✅解答 &#x1f3af;移除元素&#x1f4da;题目内容✅解答 &#x1f3af;有序数组的平方&#x1f4da;题目内容✅解答 &#x1f3af;三数之和&#x1f4da;题目内容✅解答 &#x1f4dd;最后 &#x…...

人工智能专栏第四讲——人工智能的未来展望与机遇

目录 一、人工智能的未来展望 二、人工智能在各领域的应用 三、人工智能的机遇 四、总结...

Unity阴影(Shadow)、Shadowmap

Unity阴影&#xff08;Shadow&#xff09; 在Unity中&#xff0c;阴影&#xff08;Shadow&#xff09;是用于模拟场景中物体之间相互遮挡和光照效果的特性。阴影可以增加场景的真实感&#xff0c;并在视觉上提供深度和空间感。 Unity提供了几种阴影投射和接收的方法和技术&am…...

编程语言的四种错误处理方法,你知道几种?

错误处理是编程的一个基本要素。除非你写的是“hello world”&#xff0c;否则就必须处理代码中的错误。在本文中&#xff0c;我将讨论各种编程语言在处理错误时使用的最常见的四种方法&#xff0c;并分析它们的优缺点。 关注不同设计方案的语法、代码可读性、演变过程、运行效…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...