1. 程式人生 > >Unity2018新功能搶鮮 | C# Job System Ⅱ

Unity2018新功能搶鮮 | C# Job System Ⅱ

本文首發於“洪流學堂”微信公眾號。
洪流學堂,讓你學Unity快人幾步

上一篇文章我們講了job system,這篇文章來看看如何使用job system以及常見的問題。

Scheduling jobs工作排程

如前一節所述,作業系統依賴blittable資料和NativeContainers。要排程job,需要實現IJob介面,建立結構體的例項,填充資料並呼叫Schedule。當你安排這個job後,會返回一個可用作其他job的依賴項的job控制代碼,或者當你需要再次訪問傳遞給主執行緒上的作業的NativeContainer時,你可以等待它。

當你安排job時,job實際上不會立即開始執行。我們建立了一批作業來安排需要重新整理的作業。在ECS中是隱式重新整理的,在ECS外部,需要通過呼叫靜態函式JobHandle.ScheduleBatchedJobs()

來顯式重新整理它。

// Job將兩個浮點值相加
public struct MyJob : IJob
{
    public float a;
    public float b;
    NativeArray<float> result;
    public void Execute()
    {
        result[0] = a + b;
    }
}
//建立一個單一float的本地陣列來儲存結果。這個例子將等待作業完成,這意味著我們可以使用Allocator.Temp
NativeArray<float> result = new NativeArray<float
>(1, Allocator.Temp); //設定工作資料 MyJob jobData = new MyJob(); jobData.a = 10; jobData.b = 10; jobData.result = result; //安排作業 JobHandle handle = jobData.Schedule(); //等待作業完成 handle.Complete(); //NativeArray的所有副本指向同一個記憶體,我們可以訪問NativeArray中的結果 float aPlusB = result[0]; //釋放結果陣列分配的記憶體 result.Dispose();

如果我們有多個作業在相同的資料上執行,我們需要使用依賴關係:

public struct AddOneJob : IJob
{
    public NativeArray<float> result;
    public void Execute()
    {
        result[0] = result[0] + 1;
    }
}
NativeArray<float> result = new NativeArray<float>(1, Allocator.Temp);
//設定工作資料
MyJob jobData = new MyJob();
jobData.a = 10;
jobData.b = 10;
jobData.result = result;
//安排作業
JobHandle firstHandle = jobData.Schedule();
AddOneJob incJobData = new AddOneJob();
incJobData.result = result;
JobHandle handle = incJobData.Schedule(firstHandle);
//等待作業完成
handle.Complete();
//NativeArray的所有副本指向同一個記憶體,我們可以訪問NativeArray中的結果
float aPlusB = result[0];
//釋放結果陣列分配的記憶體
result.Dispose();

ParallelFor job

如上一節所述,排程job意味著只能有一項工作在做一件事。在一個遊戲中,想要在大量物體上執行相同操作的情況非常普遍。對於這種情況,有一個單獨的工作型別:IJobParallelFor。IJobParallelFor的行為與IJob類似,但不是單次執行得到一個結果而是一次得到批量結果。系統實際上不會為每個專案安排一個job,它會為每個CPU核心最多安排一個job,並重新分配工作負載,這些都在系統內部處理的。在排程ParallelForJobs時,必須指定要分割的陣列的長度,因為如果結構中有多個數組,則系統無法知道要將哪個陣列用作主資料。你還需要指定批次的數量。批處理計數控制你將獲得多少job,以及執行緒之間的工作重新分配的細化程度如何。擁有較低的批處理數量(如1)會使你線上程之間進行更均勻的工作分配。但是,它會帶來一些開銷,因此在某些情況下,稍微增加批次數量會更好。

//job 將兩個浮點數相加
public struct MyParallelJob : IJobParallelFor
{
    [ReadOnly]
    public NativeArray<float> a;
    [Readonly]
    public NativeArray<float> b;
    public NativeArray<float> result;
    public void Execute(int i)
    {
        result[i] = a[i] + b[i];
    }
}
var jobData = new MyParallelJob();
jobData.a = 10;  
jobData.b = 10;
jobData.result = result;
//使用結果陣列中的每個索引執行一次Execute並且每次處理過程只處理一個專案
JobHandle handle = jobData.Schedule(result.Length, 1);
//等待作業完成
handle.Complete();

常見的錯誤

這是使用job system時常見錯誤的集合:

  • 從job中訪問靜態資料:這樣做意味著你在規避所有安全系統。如果你訪問了錯誤的東西,你以非預期的方式導致Unity崩潰。(未來版本將使用靜態分析來禁止job訪問全域性變數)
  • 不重新整理schedule batches(排程批次):當你想啟動job時,需要使用JobHandle.ScheduleBatchedJobs() 重新整理schedule batches 。不這樣做會排程會無限期延遲,直到有人等待它的結果。
  • 期望引用返回:由於不能使用引用返回,不能直接修改NativeArray的內容。nativeArray[0]++;var temp = nativeArray[0]; temp++;一樣不會更新NativeAr強調內容ray中的值。(我們正在致力支援C#7,它將增加ref return並解決此問題。)
  • 不呼叫JobHandle.Complete:主執行緒可以使用資料之前要求所有的依賴項都執行完成。這意味著只檢查JobHandle.IsDone是不夠的,需要呼叫Complete來讓主執行緒取回NativeContainers的所有權。呼叫Complete還清理job debugger中的狀態。不這樣做會導致記憶體洩漏,這也適用於依賴前一幀的job來安排下一幀的job。

Unity:世界領先的遊戲,VR/AR引擎
《鄭洪智的Unity2018課》,傾盡我8年的開發經驗,結合最新的Unity2018,帶你從入門到精通。
目前預售拼團,5.5折!

相關推薦

Unity2018功能 | C# Job System

本文首發於“洪流學堂”微信公眾號。 洪流學堂,讓你學Unity快人幾步 上一篇文章我們講了job system,這篇文章來看看如何使用job system以及常見的問題。 Scheduling jobs工作排程 如前一節所述,作業系統依賴

Unity2018功能 | ShaderGraph實戰教程之溶解效果

本文首發於洪流學堂微信公眾號。 洪流學堂,讓你學Unity快人幾步 洪流學堂公眾號回覆節點,獲取ShaderGraph節點詳解PDF檔案(帶目錄)。 上次我們講了ShaderGraph的配置,建立,編輯和在材質球上的使用,這節課我們通過一個例項

Unity2018功能之Entity Component System(ECS)二

,我們簡單的介紹了ECS的概念和Entities的使用方法,我將在這篇文章中繼續深入講解ECS的框架。 首先我們先來看下面這一張圖。這是我通過ECS框架創建出來的5萬個Cube,FPS基本穩定在30左右,因為預設是實時光照,所以渲染壓力有點大,這不是我們這篇文章的討論範圍。

unity2018功能之——2D Animation System

看到一個比較有意思的新功能 有關2D骨骼動畫 看了下文件並沒有全部弄懂,查了下其他的資料基本沒有。但,最後還是弄懂了,也萌生了寫個中文教程的想法。 那麼,開幹吧 下載unity2018,新建一個專案。 把上面這張圖片放到工程裡 改

Vault 0.11 特性看: Valut Agent

inter exp pen erl nec case likely nta agent AUG 26 2018????ANDY MANOSKE The Vault team is quickly closing on the next major release of Va

SAP Hybris Commerce 6.0釋出,六大革新功能看~

SAP Hybris Commerce 6.0版本強勢來襲。針對電商的需求,SAP Hybris在客戶體驗優化、實時情景營銷、促銷模組管理、客戶服務支援,雲服務和網站後臺管理等方面對軟體進行了全新升級,一大波加強版解決方案也將隨即上線。有了6.0,您可以為客戶提供極具針對

Unity2018功能搶先預覽 | Preset功能

本文首發於“洪流學堂”微信公眾號。 洪流學堂,讓你學Unity快人幾步 Presets(預設) Preset是Unity2018的新功能。 Preset是儲存物件屬性的資源。Preset儲存在專案的Project資料夾中,使用.p

c#基於System.Net.Mail實現發送郵件功能

class rom ebo man att var () pre tex 1.添加引用   using System.Net.Mail; 2.發送郵件實現代碼 private void btnsend_Click(object sender, EventA

CJob System如何工作(4)-CJob System中的安全系統

競爭條件 編寫多執行緒程式碼時,總是存在競爭條件的風險。當一個操作的輸出取決於其控制之外的另一個過程的時間的時候,就會發生競爭條件。 競爭條件並不總是一個Bug,但它是不確定行為的來源。當競爭條件確實導致Bug時,可能很難找到問題的根源,因為它取決於時間,因此

CJob System如何工作(5)-NativeContainer

NativeContainer 安全系統複製資料的過程的缺點是它還隔離了每個副本中Job的結果。要克服此限制,您需要將NativeContainer結果儲存在一種名為NativeContainer的共享記憶體中。 什麼是NativeContainer? Nat

CJob System如何工作(6)-建立Jobs

建立Jobs 要在Unity中建立作業,您需要實現IJob介面。IJob允許您排程可以與其他正在執行的Job並行執行的單個Job。 注意:“Job”是Unity中用於實現IJob介面的任何結構的集合術語。 要建立Jobs,您需要: 建立一個繼承自IJob的結

自從昨天我發現VS2012可以編譯出支援XP的程式碼之後,我決定在GacUI裡面全面使用C++11功能

昨天研究發現,只要安裝了Update 1的Visual Studio 2012也可以編譯出支援XP的程式了。為了讓GacUI可以順利執行在XP上(雖然現在因為兩個api還不能),我一直試圖讓GacUI相容VS2010。VS2010對lambda的支援的bug很多,所以導致GacUI無法全面使用C+

C++11的功能特性對Boost庫影響

《Boost程式庫探祕——深度解析C++準標準庫》之試讀         前一陣子還看到一篇文章,說C#要重蹈C++的覆轍,這裡說的C++的覆轍是什麼呢?是指C++語言過於臃腫的功能特性,導致學習人員的流失。文章說,語言最後的威力是“開發軟體”,而不是“比拼新特性”    

C#使用System.Speech製作語音提示功能

c#實現語音閱讀以及文字轉語音檔案是基於c#的一個類庫(SpeechSynthesizer )實現的,使用該類必須要新增引用using System.Speech.Synthesis;直接是無法新增引用的,先對專案進行新增應用 示例圖 using Syst

CJob System如何工作(1)-CJob System概述

C#Job System概述 Unity C# Job System允許使用者編寫與Unity其餘部分良好互動的多執行緒程式碼,並使編寫正確的程式碼變得更加容易。 編寫多執行緒程式碼可以提供高效能的好處。其中包括顯著提高幀速率和延長移動裝置的電池壽命。 C#

[Unity2018.3功能]Prefab巢狀和變體

本文節選自洪流學堂公眾號專欄《鄭洪智的Unity2018課》,未經允許不可轉載。 洪流學堂公眾號回覆專欄,檢視更多專欄文章。 大智:“今天我們要學的內容是Prefab中全新的部分,也就是巢狀的Prefab。” 小新:“為什麼需要巢狀的Prefab呢?”

程式碼演示C#各版本功能

程式碼演示C#各版本新功能 C#各版本新功能其實都能在官網搜到,但很少有人整理在一起,並通過非常簡短的程式碼將每個新特性演示出來。 程式碼演示C#各版本新功能 C# 2.0版 - 2005 泛型 分部型別 匿名方法 可以為null的值型別 迭代器 協變和逆變 C# 3.0版 - 2007 自動實現的

九個令人興奮的功能將與Java 9 展示兩點

java googl pre api ogl body 特性 gen 大神 HTTP/2 Java 9 中有新的方式來處理 HTTP 調用。這個遲到的特性用於代替老舊的 `HttpURLConnection` API,並提供對 WebSocket 和 HTTP/2 的支持。

Kafka 0.11版本功能介紹 —— 空消費組延時rebalance

次數 新功能 ins 效果 可控 size style soft font   在0.11之前的版本中,多個consumer實例加入到一個空消費組將導致多次的rebalance,這是由於每個consumer instance啟動的時間不可控,很有可能超出coordinato

SYRefresh 一款簡潔易用的刷控件 支持tableview,collectionview水平垂直刷功能

thead res 技術分享 oot nvi ring ble .com tro SYRefresh 地址: https://github.com/shushaoyong/SYRefresh 一款簡潔易用的刷新控件 示例程序: 默認刷新控件使用方法: //添加頭部刷新控