日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[MetalKit]34-Working-with-memory-in-Metal内存管理

發(fā)布時間:2025/4/5 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [MetalKit]34-Working-with-memory-in-Metal内存管理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本系列文章是對 metalkit.org 上面MetalKit內(nèi)容的全面翻譯和學(xué)習(xí).

MetalKit系統(tǒng)文章目錄


今天我們關(guān)注一下使用GPU時的內(nèi)存管理.Metal框架將內(nèi)存資源定義為MTLBuffer對象,它是分配的無類型,無格式的內(nèi)存(任何數(shù)據(jù)類型),MTLTexture對象則是分配的格式化內(nèi)存來保存圖片數(shù)據(jù).我們在本文中只關(guān)注緩沖器.

創(chuàng)建MTLBuffer對象時有三種選項:

  • makeBuffer(length:options:) 創(chuàng)建一個MTLBuffer對象并分配一塊新內(nèi)存.
  • makeBuffer(bytes:length:options:) 從一片已經(jīng)存在的區(qū)域復(fù)制數(shù)據(jù)到一塊新分配的內(nèi)存.
  • makeBuffer(bytesNoCopy:length:options:deallocator:) 重用一塊已經(jīng)存在的內(nèi)存.

讓我們創(chuàng)建一組緩沖器,看看數(shù)據(jù)是如何被傳遞到GPU的,及如何回傳給CPU.我們首先創(chuàng)建一塊緩沖器給輸入和輸出數(shù)據(jù),并給它們初始化一些值:

let count = 1500 var myVector = [Float](repeating: 0, count: count) var length = count * MemoryLayout< Float >.stride var outBuffer = device.makeBuffer(bytes: myVector, length: length, options: []) for (index, value) in myVector.enumerated() { myVector[index] = Float(index) } var inBuffer = device.makeBuffer(bytes: myVector, length: length, options: []) 復(fù)制代碼

新的MemoryLayout< Type >.stride語法在Swift 3被引入,來替代老的strideof(Type)函數(shù).同時,因為內(nèi)存排列的原因我們用.stride替代了.size.stride是指針增長時移動的字節(jié)數(shù).下一步是把我們緩沖器告訴命令編碼器:

encoder.setBuffer(inBuffer, offset: 0, at: 0) encoder.setBuffer(outBuffer, offset: 0, at: 1) 復(fù)制代碼

注意: <Metal最佳實踐指南>指出當我們的數(shù)據(jù)小于4KB(例如一個千位的浮點數(shù))時就避免創(chuàng)建緩沖器.在本例中我們應(yīng)該使用setBytes()函數(shù)來代替創(chuàng)建緩沖器.

最后一步是讀取GPU通過contents() 函數(shù)返回的數(shù)據(jù),綁定內(nèi)存數(shù)據(jù)到我們的輸出緩沖器上:

let result = outBuffer.contents().bindMemory(to: Float.self, capacity: count) var data = [Float](repeating:0, count: count) for i in 0 ..< count { data[i] = result[i] } 復(fù)制代碼

Metal資源必須被配置好,以便快速內(nèi)存訪問和驅(qū)動器性能優(yōu)化.資源的儲存模式允許我們定義緩沖器和紋理的儲存位置和訪問權(quán)限.如果你再看一眼上面我們創(chuàng)建緩沖器的地方,我們使用了默認([])的儲存模式.

所有的iOS和tvOS設(shè)備支持unified memory model統(tǒng)一內(nèi)存模型,它可以讓CPU和GPU共享系統(tǒng)內(nèi)存,而macOS設(shè)備支持discrete memory model離散內(nèi)存模型即GPU擁有自己的內(nèi)存.在iOS和tvOS中,Shared模式(MTLStorageModeShared)定義了系統(tǒng)內(nèi)存可以被CPU和GPU訪問,而Private模式(MTLStorageModePrivate)定義系統(tǒng)內(nèi)存只能被GPU訪問.Shared模式是所有三種操作系統(tǒng)中的默認儲存模式.

除了這兩種儲存模式外,macOS還有一種Managed模式(MTLStorageModeManaged),它為一種資源定義了一對同步內(nèi)存,一個副本在系統(tǒng)內(nèi)存中,另一個在視頻內(nèi)存中來獲得更快的CPU和GPU本地訪問.

現(xiàn)在讓我們看看當我們將數(shù)據(jù)緩沖器發(fā)送給GPU時,GPU上面發(fā)生了什么.下面是個典型的頂點著色器例子:

vertex Vertices vertex_func(const device Vertices *vertices [[buffer(0)]], constant Uniforms &uniforms [[buffer(1)]], uint vid [[vertex_id]]) {... } 復(fù)制代碼

Metal Shading Language實現(xiàn)了地址空間修飾詞來指定當函數(shù)變量或參數(shù)分配時的內(nèi)存區(qū)域:

  • device - 指緩沖器內(nèi)存對象,從設(shè)備內(nèi)存池中分配,既可讀又可寫除非前面有const關(guān)鍵詞就是只讀的.
  • constant - 指緩沖器內(nèi)存對象,從設(shè)備內(nèi)存池中分配,但是是read-only只讀的.程序作用域內(nèi)的變量必須被聲明為常量地址空間,并在聲明語句中被初始化.常量地址空間為多個實例在執(zhí)行圖形或內(nèi)核函數(shù)時訪問緩沖器中的同一塊位置的做了優(yōu)化.
  • threadgroup - 僅用來分配內(nèi)核函數(shù)中使用的變量,它們是為每個執(zhí)行內(nèi)核的線程組分配的,被線程組內(nèi)的所有線程共享,只在執(zhí)行內(nèi)核的線程組的生命周期內(nèi)才存在.
  • thread - 指每個線程的內(nèi)存地址空間.分配在這個地址空間的變量對其它線程是不可見的.在圖形或內(nèi)核函數(shù)中聲明的變量是分配在線程地址空間的.

作為獎勵,讓我們也看一下在Swift 3中另一種訪問內(nèi)存位置的方法.這段代碼是從前面的文章The Model I/O framework中摘抄的,所以我們就不再講解體素的細節(jié)了.只要想著我們需要遍歷一個數(shù)組來獲取值:

let url = Bundle.main.url(forResource: "teapot", withExtension: "obj") let asset = MDLAsset(url: url) let voxelArray = MDLVoxelArray(asset: asset, divisions: 10, patchRadius: 0) if let data = voxelArray.voxelIndices() {data.withUnsafeBytes { (voxels: UnsafePointer<MDLVoxelIndex>) -> Void inlet count = data.count / MemoryLayout<MDLVoxelIndex>.sizelet position = voxelArray.spatialLocation(ofIndex: voxels.pointee)print(position)} } 復(fù)制代碼

在本例中,MDLVoxelArray對象有了個名為spatialLocation()的函數(shù),它讓我們用一個MDLVoxelIndex類型的UnsafePointer指針來遍歷數(shù)組,并通過每個位置的pointee來訪問數(shù)據(jù).在本例中,我們只打印出地址中的第一個值,但一個簡單的循環(huán)可以讓我們得到所有的數(shù),像這樣:

var voxelIndex = voxels for _ in 0..<count {let position = voxelArray.spatialLocation(ofIndex: voxelIndex.pointee)print(position)voxelIndex = voxelIndex.successor() } 復(fù)制代碼

源代碼source code已發(fā)布在Github上.

下次見!

總結(jié)

以上是生活随笔為你收集整理的[MetalKit]34-Working-with-memory-in-Metal内存管理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 黄在线免费看 | 久久亚洲欧洲 | 亚洲色p| 亚洲一区在线观 | 国产又大又粗又爽 | 国产婷婷色一区二区 | 精品久久网 | 51精品国自产在线 | 狠狠操狠狠操狠狠操 | 日韩国产欧美一区二区 | 葵司ssni-879在线播放 | 欧美日韩国产精品综合 | 欧美日韩国产成人在线 | 全黄一级男人和女人 | 超碰狠狠干 | 日韩熟妇一区二区三区 | 日韩一区二区三区视频 | 国内性视频| 户外少妇对白啪啪野战 | 秋霞国产 | 国产精品久久久久久亚洲 | 日韩一本在线 | 国产精品福利影院 | 久久精品国产网红主播 | 国产福利在线观看视频 | 性一交一乱一精一晶 | 久久国产精品久久久久久电车 | 五月天婷婷色综合 | 日本a天堂| 超碰88| 成人免费福利 | 亚洲国产精品美女 | 已满18岁免费观看电视连续剧 | 久久99精品波多结衣一区 | 欧美一级淫片免费视频魅影视频 | 97蜜桃网 | 超碰97在线看 | 狠狠操很很干 | 浓精喷进老师黑色丝袜在线观看 | 好吊日在线观看 | 国产一区二区三区视频免费在线观看 | av第一区| 久久综合九色综合欧美狠狠 | 欧美看片| www.蜜桃av.com | 性做久久久久久久久 | 亚洲精品99999 | 男女搞鸡网站 | 亚洲天堂导航 | 中文字幕一区二区三区精彩视频 | 插插操操 | 欧美xxxx18国产| 婷婷另类小说 | 在线一区二区三区视频 | 国产精品成人网 | 天堂av在线中文 | 亚洲精品成人无码毛片 | 狠狠做深爱婷婷综合一区 | 四虎黄网 | 国产精欧美一区二区三区蓝颜男同 | 日韩不卡毛片 | 无码人妻精品一区二区蜜桃色欲 | 97人人射| www.男人天堂.com | 亚洲自拍p | 日韩一区二区三区精 | 久久成人一区 | 精品人妻一区二区三区日产乱码 | 精品国产一 | 日韩国产欧美在线视频 | 少妇光屁股影院 | 台湾极品xxx少妇 | 国产精品久久中文字幕 | 婷婷综合另类小说色区 | 国产20页 | 隔壁人妻偷人bd中字 | 午夜精品久久久久久久99热浪潮 | 亚洲av久久久噜噜噜噜 | 在线观看av黄色 | 日韩一级免费看 | 五月婷婷狠狠干 | 先锋影音制服丝袜 | 久久久老熟女一区二区三区91 | 成品人视频ww入口 | 国产欧美日韩精品在线 | 99re只有精品 | www.污网站 | 德国性猛交xxxxhd | 青青草原成人网 | www操| 波多野结衣mp4 | 理论片国产 | 91极品视觉盛宴 | 最新永久地址 | 久久久久久久黄色片 | 91成人网页| 别揉我奶头一区二区三区 | 天天天天躁天天爱天天碰2018 | 后入内射无码人妻一区 |