jjzjj

iOS - GPU 加速矩阵转置、乘法和特征分解困境

coder 2023-10-01 原文

我正在开发一个需要在 iOS 平台上使用向量和矩阵的库。我决定研究 OpenGLES,因为我计划进行的矩阵和向量操作(主要是转置、矩阵乘法和特征分解)绝对可以从 GPU 加速中受益。

问题是我不太熟悉 OpenGLES,老实说这可能不是最佳选择。如果我要使用 OpenGLES,我是否必须手动编写执行矩阵转置、乘法和特征分解的算法?或者是否有其他 Apple 或第 3 方框架可以帮助我完成这些任务。

然而,主要的分歧是我希望这些操作能够进行 GPU 加速。


我将使用 Accelerate Framework 和矢量化算法实现我的程序,然后测试它是否足够快以达到我的目的,如果不够快,则尝试 GPU 实现。

最佳答案

作为组合状态,Accelerate 使用 SIMD 来加速其许多功能,但它是基于 CPU 的。对于较小的数据集,这绝对是可行的方法,但在 GPU 上运行可以明显优于它,对于足够大的数据集以及易于并行化的操作。

为了避免自己编写所有 OpenGL ES 交互代码,您可以查看我的 GPUImage框架,它在 Objective-C 中封装了片段着色器操作。特别是,您可以使用 GPUImageRawDataInput 和 GPUImageRawDataOutput 类将原始字节数据输入 GPU,然后使用自定义片段着色器对其进行操作。

矩阵转置操作可以快速实现,因为所有矩阵元素都是相互独立的。矩阵乘以常数或小矩阵也很容易做到,但我不确定如何正确缩放两个大矩阵的乘法。同样,我没有一个很好的本征分解实现,我可以立即指出。

处理片段着色器处理的缺点是默认情况下 OpenGL ES 在每个像素处接收和输出 4 字节 RGBA 值。您可以在较新的设备上将其更改为半 float ,我知道其他人已经使用此框架完成了此操作,但我自己还没有尝试过。您可以将单个浮点值打包成 RGBA 字节并在最后解包,作为将此数据传入和传出 GPU 的另一种方法。

最新的 A7 设备对 OpenGL ES 3.0 的支持为处理 float 据提供了一些其他机会。您可以使用顶点数据而不是纹理输入,这样您可以为每个顶点提供四个 float 并在最后提取这些 float 。 Bartosz Ciechanowski 有 a very detailed writeup of this on his blog .对于 GPGPU 操作,这可能是一种更好的通用方法,但如果您可以让您的操作针对片段着色器中的纹理数据运行,您将看到最新硬件的巨大加速(iPhone 5S 可以比 iPhone 5S 快 100-1000 倍在这方面,iPhone 4 的顶点处理和 CPU 速度几乎没有那么快地提高)。

关于iOS - GPU 加速矩阵转置、乘法和特征分解困境,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21444982/

有关iOS - GPU 加速矩阵转置、乘法和特征分解困境的更多相关文章

  1. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  2. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  3. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  4. 旋转矩阵的几何意义 - 2

    点向量坐标矩阵的几何意义介绍旋转矩阵的几何含义之前,先介绍一下点向量坐标矩阵的几何含义点:在一维空间下就是一个标量,如同一条直线上,以任意某一个位置为0点,以一定的尺度间隔为1,2,3...,相反方向为-1,-2,-3...;如此就形成了一维坐标系,这时候任何一个点都可以用一个数值表示,如点p1=5,即即从原点出发沿着x轴正方向移动5个尺度;点p2=-3,负方向移动3个尺度;     在一维坐标系上过原点做垂直于一维坐标系的直线,则形成了二维坐标系,此时描述一个点需要两个数值来表示点p3=(3,2),即从原点出发沿着x轴正方向移动3个尺度,在此基础上沿着y轴正方向移动两个尺度的位置就是点p3。

  5. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  6. ruby - ruby 乘法语句中星号中断语法前的空格 - 2

    在添加一些空格以使代码更具可读性时(与上面的代码对齐),我遇到了这个:classCdefx42endendm=C.new现在这将给出“错误数量的参数”:m.x*m.x这将给出“语法错误,意外的tSTAR,期待$end”:2/m.x*m.x这里的解析器到底发生了什么?我使用Ruby1.9.2和2.1.5进行了测试。 最佳答案 *用于运算符(42*42)和参数解包(myfun*[42,42])。当你这样做时:m.x*m.x2/m.x*m.xRuby将此解释为参数解包,而不是*运算符(即乘法)。如果您不熟悉它,参数解包(有时也称为“spl

  7. ruby - cucumber 特征和步骤定义 - 2

    我是Cucumber测试的新手。我创建了两个特征文件:events.featurepartner.feature并将我的步骤定义放在step_definitions文件夹中:./step_definitions/events.rbpartner.rbCucumber似乎在所有.rb文件中查找步骤信息。有没有办法限制该功能查看特定的步骤定义文件?我之所以要这样做,是因为即使我使用了--guess标志,我也会遇到不明确的匹配错误。我之所以要这样做,有以下几个原因。我正在测试CMS,并希望在不同的功能中测试每种不同的内容类型(事件和合作伙伴)。事件.特征Feature:AddpartnerA

  8. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

  9. ruby-on-rails - 浮点乘法的 Ruby 奇怪问题 - 2

    有没有人用ruby​​解决这个问题:假设我们有:a=8.1999999我们想将它四舍五入为2位小数,即8.20,然后乘以1,000,000得到8,200,000我们是这样做的;(a.round(2)*1000000).to_i但是我们得到的是8199999,为什么?奇怪的是,如果我们乘以1000、100000或10000000而不是1000000,我们会得到正确的结果。有人知道为什么吗?我们正在使用ruby​​1.9.2并尝试使用1.9.3。谢谢! 最佳答案 每当你在计算中得到时髦的数字时使用bigdecimalrequire'bi

  10. ruby-on-rails - 特征未注册 : attribute name - 2

    完成这个有困难。我正在使用seed.rb+factory_girl来使用rakedb:seed填充数据库。(我知道固定装置存在,但我想以这种方式完成,这只是一个示例,数据库将填充复杂的关联对象。)我的种子.rb:require'factory_girl_rails'["QM","CDC","SI","QS"].eachdo|n|FactoryGirl.create(:grau,nome:n)end还有我的/factories/graus.rbFactoryGirl.definedofactory:graudonomeendend但是当我运行时:rakedb:seed我得到:rakeab

随机推荐