大多数浏览器和
Developer App 均支持流媒体播放。
-
适用于 Swift 的 Accelerate 简介
Accelerate 框架提供了数百种计算函数,这些函数都针对设备运行的系统架构进行了高度优化。学习如何直接在 Swift 中使用所有这些强大的函数。了解强大的矢量编程如何为您的 iOS、macOS、Apple TVOS 和 watchOS app 提供卓越的性能。
资源
相关视频
WWDC21
-
下载
你好 我是Simon Gladman 我是矢量和数字团队的一员 在本次演讲中 我会介绍两个主题 第一是我们为Accelerate 设计新Swift Overlay 第二个是使用LINPACK 基准来测试Accelerate 的性能表现 在我们深入了解 Swift Overlay之前 我们来确切地回顾一下 什么是Accelerate框架
Accelerate的主要使用 目的是提供许多 低级数学基元 它在CPU上运行 支持图片和信号处理 向量运算 线性代数 和机器学习 这些基元大多数是通过手动调整 给处理器的微体系结构的 这意味着我们获取了极佳的性能表现 这个性能表现会直接转变为节能 那么 如果你是一个app开发者 使用Accelerate框架 不仅会让你的app运行更快 你的电池寿命也会更长
我们提供的基元能 在所有的Apple平台运行 这不只包含macOS和iOS 也同样支持 watchOS和tvOS 这意味着你的用户能 获得一致的更好体验
Accelerate库非常强大 但到现在为止 它们的用户界面对 Swift开发者还不太友好 我们来看一下四个库 以及新创建的对 Swift友好的API 来使得在Swift项目中使用 Accelerate变得非常简单 关于这四个库 我们将主要关注: vDSP提供的 数字信号处理运算 包括对大向量的运算 傅里叶变换 双二次过滤 和强大的类型转换
vForce提供的运算和超越函数 包括三角和对数运算 正交提供的函数的数值积分 vImage提供了一个多种类 的图像处理函数 它已被集成至Core Graphics 和Core Video
Accelerate通过向量化 来实现它优异的性能表现
为了了解向量化 我们首先来看一下一个简单的运算 在一个数组的元素中使用标量的代码 如果 比如你写的代码 一个数组中的每个元素和 另一个数组对应的元素相乘 你使用了一个for循环 每对元素都被分散地加载 相互相乘 保存结果 那么 当a和b中的第一个元素 相乘之后 成为c的第一个元素 第二对被处理了 接着 是第三对 以及 最后是第四对
不过 如果你在 处理一个数组里的元素 使用Accelerate 你的运算会在 单指令多数据中被实现 或simD寄存器 这些寄存器能 在多个数据项中执行相同的指令 通过将多个这些物件打包成 一个单个的寄存器 比如一个单个128位的寄存器 实际上能存储 4个32位的浮点值 所以 一个矢量乘法操作 能同时相乘4对元素 这意味着这个任务不仅会被加速执行 它也会更显著地节能
我们刚才看到的乘法函数 是Accelerate的数字 信号处理库vDSP的一部分 那么 我们从新的Swift API是怎样通过 使用vDSP简化使用方式来开始吧
vDSP提供了矢量化数字 信号处理功能 包括傅里叶变换 双二次过滤 卷积和相关 更进一步 vDSP也提供了 一些强大的更常规的功能 包括元素级算术和类型转换 所以 即使你还没有一个迫切需求 比如计算两个信号之间的连贯性 你可能会发现 vDSP的常规运算程序 为你app的性能表现 提供了一个解决方案
我们来看看一些基本的运算 一个例子: 已知4个单精度值的数组 你需要计算 数组的二乘二的元素和 其他两个的各个元素都不同 使用一个for循环
来互乘这些结果 是这个问题的一个非常合理的选择 以及计算这些预期结果 这是你如何使用vDSP 经典的API来计算性能 使用vDSP大约比for 循环快三倍
这是使用我们新的为vDSP 设计Swift API相同的运算 我们暴露了 新的Swift友好的函数 通过我们的vDSP的命名空间 你能看到函数和 参数名称解释了操作 因为新的函数使用了相似的类型 包括数组和数组分片 而不是指针 你不再需要明确地传递数值 所以整个函数调用更直观 和更简洁了
传递一个初始化结果数组 提供了最好的性能表现 为了进一步的性能提升 你当然可以在其他操作中 重复使用那个数组 不过 我们也提供了 自调度函数 这些利用了Swift新的功能 来访问一个数组里未初始化的缓冲 返回运算的结果 虽然没有传递 现有的存储那么快 它还是比标量方式要快的 以及 在一些使用场景 它会简化你的代码
另一个常见的任务是 vDSP能够矢量化的 是类型转换 这个例子将一个具有双精度值 的数组转换为 16位的无符号整数的值 舍入到零
标量版本使用了显式四舍五入映射 再一次 这是一个 完全合理的技术使用 但vDSP能矢量化这个任务来 提升性能
在这个例子中 vDSP大约比之前的 标量实现快4倍
vDSP函数所在的新的Swift 版本提供了一个清晰的接口 这个函数获取一个源函数 你应该将每个元素转换成整型 和一个枚举来指定rounding
vDSP提供了傅里叶变换 在时域和频域之间 将一维数据转换至二维数据
一个信号的正向傅里叶变换 分解它成为它的组件的信号波 那就是频域所代表的 相反地 一个频域所展现的逆变换 重建了原始信号 那是时域所展现的 傅里叶变换在信号和 图像处理中有许多应用 比如只要一个音频信号被正向转换了 你可以很容易的减小或 增大一定的频率来平衡音频
经典的API是易于理解的 如果你对它熟悉 你从创建设置对象开始 指定元素的数量 你想要的转换和定位 接着 在创建完两个数组来获取结果之后 你调用执行函数 只要你在结束之后 你需要记得销毁设置 来释放为它分配的资源
新的API简化了设置对象的实例化 转换本身是一个带有 DFT实例参数名字的方法 现在 你不需要担心释放资源 我们会为你实现
就像我们看到的vDSP函数 它有一个自调度版本的转换函数 它为你创建和返回返回值的数组
如果你使用音频数据 你可能会熟悉双二次或 双二阶滤波器 双二阶滤波器能用来平衡音频 来形成频率响应 比如 它允许你能 移除低或高的频率
vDSP的双二阶功能 处理单个或多声道信号 使用一组单个过滤器 叫做sections的对象 过滤器是级联的 就是说它们是按顺序排列的 整个信号依次通过每个过滤器 过滤器被定义为一系列系数 它会被代入这里的这个方程中
在这里例子中 这些值来自一个低通滤波器 就是说 一种减少高频的滤波器 这是使用vDSP经典的API代码 来创建双二阶设置 使用之前的幻灯片的系数
这里是 运用双二阶过滤器 到一个叫做signal的数组 返回返回值到一个 叫做output的数组的代码 我们来看一下使用一个 新的API来实现相同的功能
如你所见 新的API大大地简化了 双二阶结构的创建 你很容易地传递 系数到双二阶初始化函数 指定频道的数量和部分
将双二阶过滤器运用到一个信号 是一个单次函数调用
现在我们来看一下新的API 我们为Accelerate的库 和对大的数组 vForce快速的数学运算创建的
vForce提供了vDSP 所没有的超越函数 这些包括指数 对数和三角操作
一个vForce的典型的例子 可能被用来计算一个大数组中 每个元素的平方根 这段代码的标量版本可以使用映射
vForce提供了一个矢量化函数 来计算平方根 在一些使用场合 它会 比标量的实现快10倍以上
新的Swift Overlay 提供了一个和vDSP 函数一致的新API 提供了向量化的性能表现 和能源效率的好处
就和我们早些时候看到的很类似 这是一个自调度版本 它会返回一个数组 包含了提供的数组中 每个元素的平方根
接下来 我们来看看我们 为正交创建的新的API
正交是判定一条曲线下区域 的一项有历史意义的条款 它提供了一个在有限或无限区间内 近似明确的集成函数 在示例中 我们会使用 正交来估量半圆的面积 这里的绿色的部分 通过对所示函数进行积分
很像vDSP的双二阶代码 需要相当多的代码来使用 已有的正交的API 第一步是定义一个 描述要集成函数的结构体
第二步是定义集成选项 包括集成算法
最后 使用选项定义的函数 你能使用正交积分函数来进行整合
新的API简化了代码 好处之一是你能指定被积函数 就是说 被集成的函数 作为一个交易的闭包 而不是一个C函数的指针 这意味着你能很容易的传值到 被积函数
你也要留意积分器现在 是拥有关联值的枚举 所以每次间隔无需提供没有必要的点 或是这里的最大间隔
比如 你可以传递枚举给全局自适应积分器 为间隔和最大间隔指定点
现在 我们来看一下我们为 Accelerate图像处理库 vImage创建的新的API
vImage是一个包含了 丰富的图片处理工具集的库 它被设计在Core Graphics 和Core Video间无缝运作 它包含了比如阿尔法混合 格式转换 直方图操作 卷积 几何学 以及形态的操作
我们新的Swift API 引入了许多新功能 来让大家在Swift中 更容易和简单地使用vImage 我们实现了一个选项集标记 vImages 抛出了Swift错误 我们隐藏了一些可变性的需求 以及处理非托管类型
如果你在使用 Core Graphics图片 这是一个常见的工作流 来将图片数据传入到 一个vImage缓冲中
首先 你需要创建一个 CGImagesFormat描述 接下 实例化一个vImage缓冲 在图片中初始化那个缓冲 最后 以非Swift的方式来检查错误 对于一个常见的操作 有很多样板代码
新的API将所有的那段代码 打包成了一个可抛的初始化器
不过 因为我们等会将要使用一个 CGImagesFormat 这是一个使用新的API 分两步实现的类似功能 我们使用一个CGImage为CGImageFormat 添加了一个新的初始化器 和一个额外的缓冲初始化器 它接受了一个CGImage 和一段明确形式的描述
只要你完成了一个缓冲 这是经典的vImage函数 用来在缓冲的内容中 创建一个CGImage 以及我们的新API 也使用一个新的CGImage方法 来简化了那个操作 它使用了我们刚从图片生成的形式
vImage有一个重要的用例 就是在不同的域和形式之间转换 vImage 是一个任意到任意的转换器 能在Core Video和 Core Graphics间转换 且在不同Core Graphics 形式之间转换
比如 你可能想要转换一个CMYK Core Graphics图片至RGB
这个已有的API创建了一个转换器 接受转换的源和目标格式 返回一个非托管转换器
你获取到转换器的托管引用 传递它给实现转换的函数
我们的新API为已有的转换器类型 添加了一个新的静态make函数 它会返回一个转换器实例
转换由转换器实例的 转换方法完成 最后 我们来了解使用 Core Video图片格式 在一个典型的例子中 你可能想要从 一个Core Video 像素缓冲中创建一个图片格式描述 和计算它的通道数量 这是经典的vImage API 需要从一个像素缓冲中 创建一个图片形式描述的代码 以及获取它的通道数量
新的API用两行代码 提供了相同的功能 你使用一个新的静态make函数 创建了一个来自一个像素 缓冲的Core Video 图片格式的实例 很简单的就访问到它的通道数量属性
这是新的API一小部分的简略介绍 我们现在来看一下 LINPACK基准 来看看它和Accelerate比 有多快和多节能 LINPACK基准 出自于LINPACK库 它开始是一组例程 来提供快速的计算机线性代数
它之后被包含在一个叫做 LApack的库里 它代表着线性代数软件包 LApack被设计用来在调用 缓存时利用好这些新的功能 LApack是由许多阻塞算法组成 这些算法创建在另一个叫做 BLAS库的顶部 它代表着基本的线性代数子例程 我们会在之后的演讲中了解 关于BLAS的更多内容 现在 请记住LINPACK基准 在LApack顶部运行 就是在BLAS的顶部运行
LINPACK基准衡量 一个平台多快能解决一个 一般线性方程组 它包含两个步骤 矩阵分解步骤 接下来的一步是倒推法 通过修正算法 我们能看到不同平台 运行算法时的效果如何 它为我们提供了一个比较 不同平台的方法 LINPACK基准随着时间在 不断发展 最初 它解决了一个 100x100的系统 之后是1000x1000的系统
现在最经常使用的变量 是无拘束变量 问题的尺寸可以是你想要的任何大小 这是我们今天会运行的变量
我们将在一部iPhone 10S 上比较LINPACK的性能表现 最上面 橘色的那个 我们将会运行一个未经优化 的LINPACK 这个Linpack基准 没有使用accelerate框架 它依赖没有优化正在运行 的进程的软件 我们来看看它是怎样的
我们会将它和使用 Accelerate框架做对比 也就是说 我们将会在相同的 平台运行相同的基准 但使用Accelerate框架 它会调整平台
我们能看到使用了 Accelerate框架的那个 快了超过24倍 这不仅会节约时间 也节能 它会延长电池使用寿命 我们现在来改变方式 来看一下LINPACK基准 GEMM的主要使用日常
如我所说 LINPACK 在LApack上运行 创建在BLAS上面 BLAS里的一个叫做 GEMM的例程 它代表着一般的矩阵乘法器 这个例程被用来实现BLAS 中的一些其他阻塞例程 它们在LApack的 阻塞算法中被使用 最显著的是矩阵分解和解算器例程 因此 GEMM有时被用来 作为性能表现的一个代理 为了本次演讲 我们要特别地来看一下GEMM 的单精度变量
这里 我们将要比较Eigen库 和Accelerate的性能表现 Eigen库 和Accelerate框架都 会在一部 iPhone 10S上面运行 它们都会运行一个单精度 的矩阵乘法器 我们来看看Eigen的表现
Eigen的最高速度约为510 亿次浮点运算/秒 现在我们来看一下 Accelerate的表现
可以看到Accelerate框架 在相同的平台 大概比Eigen快了2.5倍 这是因为Accelerate 框架对平台进行了手动调整 它允许我们能完全利用好平台 能提供的优势 那么 如果你是一个开发者 在app中用Accelerate 会提供更好的性能表现 这个性能表现更节能 它意味着更长的电池寿命 和一个对用户整体更好的体验
总结 Accelerat提供了 大规模的数学计算的功能 更快和节能的图像点运算 现在我们加入了一个 Swift友好的API 它让Accelerate库更易用 这样你的用户会从 性能表现和节能中受益 请访问我们的网站 我们提供了示例 文章 和广泛覆盖了整个 Accelerate框架的 参考材料 非常感谢大家
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。