精品国产一级在线观看,国产成人综合久久精品亚洲,免费一级欧美大片在线观看

技術(shù)帖:GPU上的高性能C#——Hybridizer

責(zé)任編輯:editor006

作者:smart編譯

2017-12-25 16:41:23

摘自:it168網(wǎng)站

Hybridizer是來(lái)自Altimesh的編譯器,可以讓人們采用C 代碼或 NET程序集編程GPU和其他加速器。圖7由于虛函數(shù)調(diào)用而實(shí)現(xiàn)的低帶寬  虛函數(shù)表會(huì)導(dǎo)致更多的注冊(cè)壓力,并防止內(nèi)聯(lián)。

Hybridizer是來(lái)自Altimesh的編譯器,可以讓人們采用C#代碼或.NET程序集編程GPU和其他加速器。Hybridizer使用修飾符號(hào)來(lái)表達(dá)并行性,可以生成針對(duì)多核CPU和GPU優(yōu)化的源代碼或二進(jìn)制文件。在這篇博文中演示了CUDA的目標(biāo)。

Hybridizer:GPU上的高性能C

圖1 Hybridizer編譯管線

圖1顯示了Hybridizer編譯管線。使用Parallel.For之類的并行化模式,或者像在CUDA中一樣明確地分配并行工作,可以從加速器的計(jì)算能力中受益,而無(wú)需了解其內(nèi)部架構(gòu)的所有細(xì)節(jié)。下面是一個(gè)使用Parallel.For和lambda的簡(jiǎn)單示例。

Hybridizer:GPU上的高性能C

人們可以使用NVIDIA Nsight Visual Studio Edition在GPU上調(diào)試和分析這些代碼。 Hybridizer實(shí)現(xiàn)了先進(jìn)的C#功能,其中包括虛函數(shù)和泛型。

在哪里可以獲得Hybridizer

Hybridizer有兩個(gè)版本:

Hybridizer Software Suite:支持CUDA,AVX,AVX2,AVX512目標(biāo)和輸出源代碼。這個(gè)源代碼需要被審查,這在某些企業(yè)(如投資銀行)是強(qiáng)制性的。Hybridizer軟件套件根據(jù)客戶要求獲得許可。

Hybridizer Essentials:僅啟用CUDA目標(biāo)并僅輸出二進(jìn)制文件。 Hybridizer Essentials是一個(gè)免費(fèi)的Visual Studio擴(kuò)展程序,沒(méi)有硬件限制。人們可以在GitHub上找到一組基本代碼示例和教育資料。這些樣本也可以用來(lái)重現(xiàn)其性能結(jié)果。

調(diào)試和分析

使用調(diào)試信息進(jìn)行編譯時(shí),可以在Microsoft Visual Studio中調(diào)試Hybridizer C#/ .NET代碼,同時(shí)在目標(biāo)硬件上運(yùn)行優(yōu)化代碼。例如,用C#編寫(xiě)的程序可以在Visual Studio中的C#文件中創(chuàng)建一個(gè)斷點(diǎn),可以瀏覽駐留在GPU上的本地變量和對(duì)象數(shù)據(jù)。

Hybridizer:GPU上的高性能C

圖2 使用Hybridizer和NVIDIA Nsight Visual Studio Edition調(diào)試GPU上運(yùn)行的C#代碼

人們可以在復(fù)雜項(xiàng)目中集成Hybridizer,即使在代碼不可用或模糊的庫(kù)中,這是因?yàn)镠ybridizer在MSIL字節(jié)碼上運(yùn)行。在博客文章中展示了使用Hybridizer加速AForge圖像處理庫(kù)而沒(méi)有修改庫(kù)的能力。在MSIL字節(jié)碼上運(yùn)行也支持在.Net虛擬機(jī)之上構(gòu)建的各種語(yǔ)言,比如VB.Net和F#。

所有這些靈活性不會(huì)以犧牲性能損失為代價(jià)。正如基準(zhǔn)測(cè)試所示,Hybridizer產(chǎn)生的代碼可以像手寫(xiě)代碼一樣執(zhí)行。人們可以使用性能分析器(例如NVIDIA Nsight和NVIDIA Visual Profiler)來(lái)測(cè)量生成的二進(jìn)制文件的性能,其性能指標(biāo)指的是原始源代碼(例如C#)。

舉一個(gè)簡(jiǎn)單的例子:Mandelbrot

作為第一個(gè)例子,演示了在NVIDIA GeForce GTX 1080 Ti GPU(Pascal架構(gòu),計(jì)算能力6.1)上運(yùn)行的Mandelbrot分形的渲染。

Mandelbrot C#代碼

以下代碼片斷顯示了plain C#。它在CPU上平穩(wěn)運(yùn)行,沒(méi)有任何性能損失,因?yàn)榇蠖鄶?shù)代碼都是屬性的修改,在運(yùn)行時(shí)沒(méi)有任何影響(例如Run方法中的EntryPoint屬性)。

[EntryPoint]

public static void Run(float[,] result)

{

int size = result.GetLength(0);

Parallel2D.For(0, size, 0, size, (i, j) => {

float x = fromX + i * h;

float y = fromY + j * h;

result[i, j] = IterCount(x, y);

});

}

public static float IterCount(float cx, float cy)

{

float result = 0.0F;

float x = 0.0f, y = 0.0f, xx = 0.0f, yy = 0.0f;

while (xx + yy <= 4.0f && result < maxiter) {

xx = x * x;

yy = y * y;

float xtmp = xx - yy + cx;

y = 2.0f * x * y + cy;

x = xtmp;

result++;

}

return result;

}

EntryPoint屬性告訴Hybridizer生成一個(gè)CUDA內(nèi)核。多維數(shù)組映射到內(nèi)部類型,而Parallel2D.For映射到2D執(zhí)行網(wǎng)格。給定幾行Boilerplate(樣板)代碼,可以透明地在GPU上運(yùn)行這些代碼。

float[,] result = new float[N,N];

HybRunner runner = HybRunner.Cuda("Mandelbrot_CUDA.dll").SetDistrib(32, 32, 16, 16, 1, 0);

dynamic wrapper = runner.Wrap(new Program());

wrapper.Run(result);

剖析

我們使用Nvidia Nsight Visual Studio Edition分析器來(lái)分析此代碼。將C#代碼鏈接到CUDA源代碼視圖中的PTX,如圖3所示。

Hybridizer:GPU上的高性能C

圖3在CUDA源代碼視圖中分析Mandelbrot C#代碼

分析器允許與CUDA C ++代碼相同的調(diào)查級(jí)別。

就性能而言,這個(gè)例子達(dá)到峰值計(jì)算FLOP / s的72.5%。這是CUDA C ++人工編寫(xiě)的相同代碼的83%。

Hybridizer:GPU上的高性能C

圖4 Profiler輸出顯示了GPU上Mandelbrot代碼的GPU利用率和執(zhí)行效率。它實(shí)現(xiàn)的效率幾乎與人工編寫(xiě)CUDA C ++代碼一樣高效。 使用Hybridizer提供的擴(kuò)展控件,可以從C#代碼中獲得更好的性能。如下面的代碼所示,其語(yǔ)法與CUDA C ++非常相似。[EntryPoint]

public static void Run(float[] result)

{

for (int i = threadIdx.y + blockIdx.y * blockDim.y; i < N; i += blockDim.y * gridDim.y)

{

for (int j = threadIdx.x + blockIdx.x * blockDim.x; j < N; j += blockDim.x * gridDim.x)

{

float x = fromX + i * h;

float y = fromY + j * h;

result[i * N + j] = IterCount(x, y);

}

}

}

在這個(gè)案例中,生成的代碼和人工編寫(xiě)的CUDA C ++代碼的性能完全相同,達(dá)到峰值FLOP/s的87%,如圖5所示。

Hybridizer:GPU上的高性能C

圖5分析人工優(yōu)化的Mandelbrot C#代碼

泛型和虛函數(shù)

Hybridizer支持設(shè)備功能中的泛型和虛函數(shù)調(diào)用。現(xiàn)代編程語(yǔ)言的這些基本概念有助于代碼模塊化并提高表達(dá)能力。但是,C#中的類型解析是在運(yùn)行時(shí)完成的,這會(huì)導(dǎo)致一些性能損失。.NET的泛型可以在保持靈活性的同時(shí)實(shí)現(xiàn)更高的性能:Hybridizer將泛型映射到C++模板,C ++模板在編譯時(shí)解析,允許函數(shù)內(nèi)聯(lián)和過(guò)程間優(yōu)化。另一方面,虛函數(shù)調(diào)用被映射到其中實(shí)例方法被注冊(cè)的虛函數(shù)表。

通過(guò)兩個(gè)屬性HybridTemplateConcept和HybridRegisterTemplate(在設(shè)備代碼中觸發(fā)實(shí)際的模板實(shí)例化)給模板實(shí)例化提示。作為一個(gè)例子,我們來(lái)看看兩個(gè)版本中的一個(gè)簡(jiǎn)單的stream benchmark,一個(gè)使用虛函數(shù)調(diào)用,另一個(gè)使用模板映射。該基準(zhǔn)依賴于一個(gè)通用的接口IMyArray暴露出下標(biāo)運(yùn)算符:

[HybridTemplateConcept]

public interface IMyArray {

double this[int index] { get; set; }

}

這些操作符必須與設(shè)備功能"Hybridized(雜交)"。為此,我們把Kernel屬性放在實(shí)現(xiàn)類中。

public class MyArray : IMyArray {

double[] _data;

public MyArray(double[] data) {

_data = data;

}

[Kernel]

public double this[int index] {

get { return _data[index]; }

set { _data[index] = value; }

}

}

虛擬功能調(diào)用

在第一個(gè)版本中,使用接口編寫(xiě)了一個(gè)流算法,沒(méi)有進(jìn)一步提示編譯器。public class MyAlgorithmDispatch {

IMyArray a, b;

public MyAlgorithmDispatch(IMyArray a, IMyArray b) {

this.a = a;

this.b = b;

}

[Kernel]

public void Add(int n) {

IMyArray a = this.a;

IMyArray b = this.b;

for (int k = threadIdx.x + blockDim.x * blockIdx.x;

k < n;

k += blockDim.x * gridDim.x) {

a[k] += b[k];

}

}

}

因?yàn)榘補(bǔ)和b上的下標(biāo)運(yùn)算符稱為接口,所以在MSIL中有一個(gè)callvirt。IL_002a: ldloc.3

IL_002b: ldloc.s 4

IL_002d: callvirt instance float64 Mandelbrot.IMyArray::get_Item(int32)

IL_0032: ldloc.1

IL_0033: ldloc.2

IL_0034: callvirt instance float64 Mandelbrot.IMyArray::get_Item(int32)

IL_0039: add

IL_003a: callvirt instance void Mandelbrot.IMyArray::set_Item(int32, float64檢查生成的二進(jìn)制表明Hybridizer在虛函數(shù)表中生成了一個(gè)查找,如圖6所示。

圖6. PTX中的虛函數(shù)調(diào)用 這個(gè)版本的算法消耗32個(gè)寄存器,并獲得271GB/s的帶寬,如圖7所示。在同一硬件上,CUDA Toolkit中的帶寬測(cè)試示例達(dá)到352GB/s。

Hybridizer:GPU上的高性能C

圖7由于虛函數(shù)調(diào)用而實(shí)現(xiàn)的低帶寬

虛函數(shù)表會(huì)導(dǎo)致更多的注冊(cè)壓力,并防止內(nèi)聯(lián)。

通用要求

采用泛型寫(xiě)了第二個(gè)版本,要求Hybridizer生成模板代碼。

[HybridRegisterTemplate(Specialize = typeof(MyAlgorithm))]

public class MyAlgorithm where T : IMyArray

{

T a, b;

[Kernel]

public void Add(int n)

{

T a = this.a;

T b = this.b;

for (int k = threadIdx.x + blockDim.x * blockIdx.x;

k < n;

k += blockDim.x * gridDim.x)

a[k] += b[k];

}

}

public MyAlgorithm(T a, T b)

{

this.a = a;

this.b = b;

}

}

使用RegisterTemplate屬性,Hybridizer將生成相應(yīng)的模板實(shí)例。然后生成內(nèi)聯(lián)函數(shù)的調(diào)用,如圖8所示。

圖8使用泛型參數(shù)生成內(nèi)聯(lián)函數(shù)調(diào)用,而不是虛函數(shù)表查找

其通用參數(shù)性能要好得多,達(dá)到339GB/s,性能提高25%(如圖9所示),帶寬測(cè)試為96%。

Hybridizer:GPU上的高性能C

圖9 由于函數(shù)內(nèi)聯(lián),泛型實(shí)現(xiàn)了更高的帶寬開(kāi)始使用Hybridizer

Hybridizer支持各種C#特性,允許代碼分解和表達(dá)。Visual Studio和Nsight(調(diào)試器和分析器)中的集成為人們提供了一個(gè)安全高效的開(kāi)發(fā)環(huán)境。即使在非常復(fù)雜的高度定制的代碼上,Hybridizer也可以實(shí)現(xiàn)出色的GPU性能。

人們可以從Visual Studio Marketplace下載Hybridizer Essentials。查看在github上的SDK。

鏈接已復(fù)制,快去分享吧

企業(yè)網(wǎng)版權(quán)所有?2010-2024 京ICP備09108050號(hào)-6京公網(wǎng)安備 11010502049343號(hào)

  • <menuitem id="jw4sk"></menuitem>

    1. <form id="jw4sk"><tbody id="jw4sk"><dfn id="jw4sk"></dfn></tbody></form>
      主站蜘蛛池模板: 宁都县| 正定县| 鄂托克旗| 河北省| 赤峰市| 盈江县| 江陵县| 手游| 图片| 扎鲁特旗| 凤山市| 禄劝| 四川省| 余干县| 花莲市| 施秉县| 河源市| 噶尔县| 乌兰浩特市| 宣城市| 富民县| 法库县| 四平市| 渑池县| 永春县| 连云港市| 小金县| 新龙县| 溧阳市| 同德县| 河源市| 乌海市| 乌鲁木齐县| 楚雄市| 肥城市| 昆明市| 扶绥县| 宜城市| 玉环县| 乾安县| 准格尔旗|