在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

快速介紹GPU的工作原理,詳細介紹當前的Julia GPU生態系統

DPVg_AI_era ? 來源:未知 ? 作者:李倩 ? 2018-10-23 09:23 ? 次閱讀

本文旨在快速介紹GPU工作原理,詳細介紹當前的Julia GPU生態系統,并讓讀者了解簡單的GPU編程是多么的容易。


GPU是如何工作的?

首先,什么是GPU?

GPU是一個大規模并行處理器,具有幾千個并行處理單元。 例如,本文中使用的Tesla k80提供4992個并行CUDA內核。 GPU在頻率,延遲和硬件功能方面與CPU完全不同,但有點類似于擁有4992個內核的慢速CPU!

“Tesla K80”

可啟用并行線程的數量可以大幅提高GPU速度,但也讓它的使用性變得更加困難。讓我們來詳細看看在使用這種原始動力時,你會遇到哪些缺點:

GPU是一個獨立的硬件,具有自己的內存空間和不同的架構。 因此,從RAM到GPU存儲器(VRAM)的傳輸時間很長。 即使在GPU上啟動內核(換句話說,調度函數調用)也會帶來較大的延遲。 GPU的時間約為10us,而CPU的時間則為幾納秒。

在沒有高級包裝器的情況下,設置內核會很快變得復雜

較低的精度是默認值,而較高的精度計算可以輕松地消除所有性能增益

GPU函數(內核)本質上是并行的,所以編寫GPU內核至少和編寫并行CPU代碼一樣困難,但是硬件上的差異增加了相當多的復雜性

與上述相關,許多算法都不能很好地移植到GPU上。

內核通常是用C/ C++編寫的,這并不是寫算法的最佳語言。

CUDA和OpenCL之間存在分歧,OpenCL是用于編寫低級GPU代碼的主要框架。雖然CUDA只支持英偉達硬件,但OpenCL支持所有硬件,但有些粗糙。

Julia的誕生是個好消息!它是一種高級腳本語言,允許你在Julia本身編寫內核和周圍的代碼,同時在大多數GPU硬件上運行!

GPUArrays

大多數高度并行的算法需要通過相當多的數據來克服所有線程和延遲開銷。因此,大多數算法都需要數組來管理所有數據,這需要一個好的GPU數組庫(array library)作為關鍵基礎。

GPUArrays.jl是Julia的基礎。它提供了一個抽象數組實現,專門用于使用高度并行硬件的原始功能。它包含設置GPU所需的所有功能,啟動Julia GPU函數并提供一些基本的數組算法。

抽象意味著它需要以CuArrays和CLArrays形式的具體實現。由于繼承了GPUArrays的所有功能,它們都提供完全相同的接口。唯一的區別出現在分配數組時,這會強制你決定數組是否位于CUDA或OpenCL設備上。關于這一點的更多信息,請參閱內存部分。

GPUArrays有助于減少代碼重復,因為它允許編寫獨立于硬件的GPU內核,可以通過CuArrays或CLArrays將其編譯為本機GPU代碼。因此,許多通用內核可以在繼承自GPUArrays的所有packages之間共享。

一點選擇建議:CuArrays僅適用于Nvidia GPU,而CLArrays適用于大多數可用的GPU。CuArrays比CLArrays更穩定,并且已經可以在Julia 0.7上運行。速度上差異不明顯。我建議兩者都試一下,看看哪個效果最好。

對于本文,我將選擇CuArrays,因為本文是為Julia 0.7 / 1.0而寫的,CLArrays仍然不支持。

性能

讓我們用一個簡單的交互式代碼示例來快速說明為什么要將計算轉移到GPU上,這個示例計算julia set:

1usingCuArrays,FileIO,Colors,GPUArrays,BenchmarkTools 2usingCuArrays:CuArray 3""" 4ThefunctioncalculatingtheJuliaset 5""" 6functionjuliaset(z0,maxiter) 7c=ComplexF32(-0.5,0.75) 8z=z0 9foriin1:maxiter10abs2(z)>4f0&&return(i-1)%UInt811z=z*z+c12end13returnmaxiter%UInt8#%isusedtoconvertwithoutoverflowcheck14end15range=100:50:2^1216cutimes,jltimes=Float64[],Float64[]17functionrun_bench(in,out)18#usedotsyntaxtoapply`juliaset`toeachelemtofq_converted19#andwritetheoutputtoresult20out.=juliaset.(in,16)21#allcallstotheGPUarescheduledasynchronous,22#soweneedtosynchronize23GPUArrays.synchronize(out)24end25#storeareferencetothelastresultsforplotting26last_jl,last_cu=nothing,nothing27forNinrange28w,h=N,N29q=[ComplexF32(r,i)fori=1:-(2.0/w):-1,r=-1.5:(3.0/h):1.5]30for(times,Typ)in((cutimes,CuArray),(jltimes,Array))31#converttoArrayorCuArray-movingthecalculationtoCPU/GPU32q_converted=Typ(q)33result=Typ(zeros(UInt8,size(q)))34foriin1:10#5samplespersize35#benchmarkingmacro,allvariablesneedtobeprefixedwith$36t=Base.@elapsedbegin37run_bench(q_converted,result)38end39globallast_jl,last_cu#we'reinlocalscope40ifresultisaCuArray41last_cu=result42else43last_jl=result44end45push!(times,t)46end47end48end4950cu_jl=hcat(Array(last_cu),last_jl)51cmap=colormap("Blues",16+1)52color_lookup(val,cmap)=cmap[val+1]53save("results/juliaset.png",color_lookup.(cu_jl,(cmap,)))

1usingPlots;plotly()2x=repeat(range,inner=10)3speedup=jltimes./cutimes4Plots.scatter(5log2.(x),[speedup,fill(1.0,length(speedup))],6label=["cuda""cpu"],markersize=2,markerstrokewidth=0,7legend=:right,xlabel="2^N",ylabel="speedup"8)

如你所見,對于大型數組,通過將計算移動到GPU可以獲得穩定的60-80倍的加速。而且非常簡單,只需將Julia array轉換為GPUArray。

有人可能認為GPU的性能受到像Julia這樣的動態語言的影響,但Julia的GPU性能應該與CUDA或OpenCL的原始性能相當。Tim Besard在集成LLVM Nvidia編譯pipeline方面做得非常出色,達到了與純CUDA C代碼相同(有時甚至更好)的性能。Tim發表了一篇非常詳細的博文,里面進一步解釋了這一點[1]。CLArrays方法有點不同,它直接從Julia生成OpenCL C代碼,具有與OpenCL C相同的性能!

為了更好地了解性能并查看與多線程CPU代碼的比較,我收集了一些基準測試[2]。

內存(Memory)

GPU具有自己的存儲空間,包括視頻存儲器(VRAM),不同的高速緩存和寄存器。無論你做什么,任何Julia對象都必須先轉移到GPU才能使用。并非Julia中的所有類型都可以在GPU上工作。

首先讓我們看一下Julia的類型:

1structTest#animmutablestruct 2#thatonlycontainsotherimmutable,whichmakes 3#isbitstype(Test)==true 4x::Float32 5end 6 7#theisbitspropertyisimportant,sincethosetypescanbeused 8#withoutconstraintsontheGPU! 9@assertisbitstype(Test)==true10x=(2,2)11isa(x,Tuple{Int,Int})#tuplesarealsoimmutable12mutablestructTest2#->mutable,isbits(Test2)==false13x::Float3214end15structTest316#containsaheapallocation/reference,notisbits17x::Vector{Float32}18y::Test2#Test2ismutableandalsoheapallocated/areference19end20Vector{Test}#<-??An?Array?with?isbits?elements?is?contigious?in?memory21Vector{Test2}?#?<-?An?Array?with?mutable?elements?is?basically?an?array?of?heap?pointers.?Since?it?just?contains?cpu?heap?pointers,?it?won't?work?on?the?GPU.

"Array{Test2,1}"

所有這些Julia類型在轉移到GPU或在GPU上創建時表現都不同。下表概述了預期結果:

創建位置描述了對象是否在CPU上創建然后傳輸到GPU內核,或者是否在內核的GPU上創建。這個表顯示了是否可以創建類型的實例,并且對于從CPU到GPU的傳輸,該表還指示對象是否通過引用復制或傳遞。

Garbage Collection

使用GPU時的一個很大的區別是GPU上沒有垃圾回收( garbage collector, GC)。這不是什么大問題,因為為GPU編寫的高性能內核不應該一開始就創建任何GC-tracked memory。

為GPU實現GC是可能的,但請記住,每個執行的內核都是大規模并行的。在~1000 GPU線程中的每一個線程創建和跟蹤大量堆內存將很快破壞性能增益,因此這實際上是不值得的。

作為內核中堆分配數組的替代方法,你可以使用GPUArrays。GPUArray構造函數將創建GPU緩沖區并將數據傳輸到VRAM。如果調用Array(gpu_array),數組將被轉移回RAM,表示為普通的Julia數組。這些GPU數組的Julia句柄由Julia的GC跟蹤,如果它不再使用,GPU內存將被釋放。

因此,只能在設備上使用堆棧分配,并且對其余的預先分配的GPU緩沖區使用。由于傳輸非常昂貴的,因此在編程GPU時盡可能多地重用和預分配是很常見的。

The GPUArray Constructors

1usingCuArrays,LinearAlgebra 2 3#GPUArrayscanbeconstructedfromallJuliaarrayscontainingisbitstypes! 4A1D=cu([1,2,3])#clforCLArrays 5A1D=fill(CuArray{Int},0,(100,))#CLArrayforCLArrays 6#Float32array-Float32isusuallypreferredandcanbeupto30xfasteronmostGPUsthanFloat64 7diagonal_matrix=CuArray{Float32}(I,100,100) 8filled=fill(CuArray,77f0,(4,4,4))#3DarrayfilledwithFloat3277 9randy=rand(CuArray,Float32,42,42)#randomnumbersgeneratedontheGPU10#Thearrayconstructoralsoacceptsisbitsiteratorswithaknownsize11#Note,thatsinceyoucanalsopassisbitstypestoagpukerneldirectly,inmostcasesyouwon'tneedtomaterializethemasangpuarray12from_iter=CuArray(1:10)13#let'screateapointtypetofurtherillustratewhatcanbedone:14structPoint15x::Float3216y::Float3217end18Base.convert(::Type{Point},x::NTuple{2,Any})=Point(x[1],x[2])19#becausewedefinedtheaboveconvertfromatupletoapoint20#[Point(2,2)]canbewrittenasPoint[(2,2)]sinceallarray21#elementswillgetconvertedtoPoint22custom_types=cu(Point[(1,2),(4,3),(2,2)])23typeof(custom_types)

"CuArray{Point, 1}"

Array Operations

許多操作是已經定義好的。最重要的是,GPUArrays支持Julia的fusing dot broadcasting notation。這種標記法允許你將函數應用于數組的每個元素,并使用f的返回值創建一個新數組。這個功能通常稱為映射(map)。 broadcast 指的是具有不同形狀的數組被散布到相同的形狀。

它的工作方式如下:

1x=zeros(4,4)#4x4arrayofzeros2y=zeros(4)#4elementarray3z=2#ascalar4#y's1stdimensiongetsrepeatedforthe2nddimensioninx5#andthescalarzget'srepeatedforalldimensions6#thebelowisequalto`broadcast(+,broadcast(+,xx,y),z)`7x.+y.+z

關于broadcasting如何工作的更多解釋,可以看看這個指南:

julia.guide/broadcasting

這意味著在不分配堆內存(僅創建isbits類型)的情況下運行的任何Julia函數都可以應用于GPUArray的每個元素,并且多個dot調用將融合到一個內核調用中。由于內核調用延遲很高,這種融合是一個非常重要的優化。

1usingCuArrays 2A=cu([1,2,3]) 3B=cu([1,2,3]) 4C=rand(CuArray,Float32,3) 5result=A.+B.-C 6test(a::T)whereT=a*convert(T,2)#converttosametypeas`a` 7 8#inplacebroadcast,writesdirectlyinto`result` 9result.=test.(A)#customfunctionwork1011#Thecoolthingisthatthiscomposeswellwithcustomtypesandcustomfunctions.12#Let'sgobacktoourPointtypeanddefineadditionforit13Base.:(+)(p1::Point,p2::Point)=Point(p1.x+p2.x,p1.y+p2.y)1415#nowthisworks:16custom_types=cu(Point[(1,2),(4,3),(2,2)])1718#Thisparticularexamplealsoshowsthepowerofbroadcasting:19#Nonarraytypesarebroadcastedandrepeatedforthewholelength20result=custom_types.+Ref(Point(2,2))2122#Sotheaboveisequalto(minusalltheallocations):23#thisallocatesanewarrayonthegpu,whichwecanavoidwiththeabovebroadcast24broadcasted=fill(CuArray,Point(2,2),(3,))2526result==custom_types.+broadcasted

ture

現實世界中的GPUArrays

讓我們直接看看一些很酷的用例。

如下面的視頻所示,這個GPU加速煙霧模擬是使用GPUArrays + CLArrays創建的,可在GPU或CPU上運行,GPU版本的速度提高了15倍:

還有更多的用例,包括求解微分方程,有限元模擬和求解偏微分方程。

讓我們來看一個簡單的機器學習示例,看看如何使用GPUArrays:

1usingFlux,Flux.Data.MNIST,Statistics 2usingFlux:onehotbatch,onecold,crossentropy,throttle 3usingBase.Iterators:repeated,partition 4usingCuArrays 5 6#ClassifyMNISTdigitswithaconvolutionalnetwork 7 8imgs=MNIST.images() 910labels=onehotbatch(MNIST.labels(),0:9)1112#Partitionintobatchesofsize1,00013train=[(cat(float.(imgs[i])...,dims=4),labels[:,i])14foriinpartition(1:60_000,1000)]1516use_gpu=true#helpertoeasilyswitchbetweengpu/cpu1718todevice(x)=use_gpu?gpu(x):x1920train=todevice.(train)2122#Preparetestset(first1,000images)23tX=cat(float.(MNIST.images(:test)[1:1000])...,dims=4)|>todevice24tY=onehotbatch(MNIST.labels(:test)[1:1000],0:9)|>todevice2526m=Chain(27Conv((2,2),1=>16,relu),28x->maxpool(x,(2,2)),29Conv((2,2),16=>8,relu),30x->maxpool(x,(2,2)),31x->reshape(x,:,size(x,4)),32Dense(288,10),softmax)|>todevice3334m(train[1][1])3536loss(x,y)=crossentropy(m(x),y)3738accuracy(x,y)=mean(onecold(m(x)).==onecold(y))3940evalcb=throttle(()->@show(accuracy(tX,tY)),10)41opt=ADAM(Flux.params(m));

1#train2fori=1:103Flux.train!(loss,train,opt,cb=evalcb)4end

accuracy(tX, tY) = 0.101

accuracy(tX, tY) = 0.888

accuracy(tX, tY) = 0.919

1usingColors,FileIO,ImageShow2N=223img=tX[:,:,1:1,N:N]4println("Predicted:",Flux.onecold(m(img)).-1)5Gray.(collect(tX[:,:,1,N]))

只需將數組轉換為GPUArrays(使用gpu(array)),我們就可以將整個計算轉移到GPU并獲得相當不錯的速度提升。這要歸功于Julia復雜的AbstractArray基礎架構,GPUArray可以無縫地集成到其中。接著,如果你省略了對轉換為GPUArray,代碼也將使用普通的Julia數組運行——但當然這是在CPU上運行。你可以通過將use_gpu = true更改為use_gpu = false并重試初始化和訓練單元格來嘗試這個操作。對比GPU和CPU,CPU運行時間為975秒,GPU運行時間為29秒 ——加速了約33倍!

另一個值得關注的好處是,GPUArrays不需顯式地實現自動微分以有效地支持神經網絡的反向傳播。這是因為Julia的自動微分庫適用于任意函數,并發出可在GPU上高效運行的代碼。這有助于幫助Flux以最少的開發人員在GPU上工作,并使Flux GPU能夠有效地支持用戶定義的函數。在沒有GPUArrays + Flux之間協調的情況下開箱即用是Julia的一個非常獨特的特性,詳細解釋見[3].

編寫GPU內核

只需使用GPUArrays的通用抽象數組接口,而不用編寫任何GPU內核,就可以做很多事了。但是,在某些時候,可能需要實現一個需要在GPU上運行的算法,并且不能用通用數組算法的組合來表示。

好的一點是,GPUArrays通過一種分層方法減少了大量的工作,這種方法允許你從高級代碼開始編寫低級內核,類似于大多數OpenCL / CUDA示例里的。它還允許你在OpenCL或CUDA設備上執行內核,從而抽象出這些框架中的任何差異。

使這成為可能的函數名為gpu_call。它可以被稱為 gpu_call(kernel, A::GPUArray, args),并將在GPU上使用參數 (state, args...) 調用內核。State是一個后端特定對象,用于實現獲取線程索引之類的功能。GPUArray需要作為第二個參數傳遞,一遍分派到正確的后端并提供啟動參數的缺省值。

讓我們使用gpu_call來實現一個簡單的map kernel:

1usingGPUArrays,CuArrays 2#OverloadingtheJuliaBasemap!functionforGPUArrays 3functionBase.map!(f::Function,A::GPUArray,B::GPUArray) 4#ourfunctionthatwillrunonthegpu 5functionkernel(state,f,A,B) 6#Iflaunchparametersaren'tspecified,linear_indexgetstheindex 7#intotheArraypassedassecondargumenttogpu_call(`A`) 8i=linear_index(state) 9ifi<=?length(A)10??????????@inbounds?A[i]?=?f(B[i])11????????end12????????return13????end14????#?call?kernel?on?the?gpu15????gpu_call(kernel,?A,?(f,?A,?B))16end

簡單來說,上面的代碼將在GPU上并行調用julia函數內核length(A) 次。內核的每個并行調用都有一個線程索引,我們可以使用它來安全地索引到數組A和B。如果我們計算自己的索引,而不是使用linear_index,我們需要確保沒有多個線程讀寫同一個數組位置。因此,如果我們使用線程在純Julia中編寫,其對應版本如下:

1usingBenchmarkTools 2functionthreadded_map!(f::Function,A::Array,B::Array) 3Threads.@threadsforiin1:length(A) 4A[i]=f(B[i]) 5end 6A 7end 8x,y=rand(10^7),rand(10^7) 9kernel(y)=(y/33f0)*(732.f0/y)10#onthecpuwithoutthreads:11single_t=@belapsedmap!($kernel,$x,$y)1213#"ontheCPUwith4threads(2realcores):14thread_t=@belapsedthreadded_map!($kernel,$x,$y)1516#ontheGPU:17xgpu,ygpu=cu(x),cu(y)18gpu_t=@belapsedbegin19map!($kernel,$xgpu,$ygpu)20GPUArrays.synchronize($xgpu)21end22times=[single_t,thread_t,gpu_t]23speedup=maximum(times)./times24println("speedup:$speedup")25bar(["1core","2cores","gpu"],speedup,legend=false,fillcolor=:grey,ylabel="speedup")

因為這個函數沒有做很多工作,我們看不到完美的擴展,但線程和GPU版本仍然提供了很大的加速。

GPU比線程示例展示的要復雜得多,因為硬件線程是在線程塊中布局的——gpu_call在簡單版本中抽象出來,但它也可以用于更復雜的啟動配置:

1usingCuArrays 2 3threads=(2,2) 4blocks=(2,2) 5T=fill(CuArray,(0,0),(4,4)) 6B=fill(CuArray,(0,0),(4,4)) 7gpu_call(T,(B,T),(blocks,threads))dostate,A,B 8#thosenamesprettymuchrefertothecudanames 9b=(blockidx_x(state),blockidx_y(state))10bdim=(blockdim_x(state),blockdim_y(state))11t=(threadidx_x(state),threadidx_y(state))12idx=(bdim.*(b.-1)).+t13A[idx...]=b14B[idx...]=t15return16end17println("Threadsindex: ",T)18println("Blockindex: ",B)

在上面的示例中,你可以看到更復雜的啟動配置的迭代順序。確定正確的迭代+啟動配置對于達到GPU的最佳性能至關重要。

結論

在將可組合的高級編程引入高性能世界方面,Julia取得了長足的進步。現在是時候對GPU做同樣的事情了。

希望Julia降低開始在GPU上編程的標準,并且我們可以為開源GPU計算發展可擴展的平臺。第一個成功案例是通過Julia packages實現自動微分,這些軟件包甚至不是為GPU編寫,因此這給了我們很多理由相信Julia在GPU計算領域的可擴展和通用設計是成功的。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • gpu
    gpu
    +關注

    關注

    28

    文章

    4922

    瀏覽量

    130818
  • 生態系統
    +關注

    關注

    0

    文章

    707

    瀏覽量

    21000

原文標題:手把手教你如何用Julia做GPU編程(附代碼)

文章出處:【微信號:AI_era,微信公眾號:新智元】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦
    熱點推薦

    GPU Render Engine詳細介紹

    硬件模塊。每個硬件對應一個或者多個引擎。本文主要介紹 render 引擎, 從 GPU 渲染的硬件單元,到用戶態頂點,命令等數據下發給 GPU 硬件執行過程等方面進行詳細
    發表于 05-30 09:54 ?1511次閱讀
    <b class='flag-5'>GPU</b> Render Engine<b class='flag-5'>詳細</b><b class='flag-5'>介紹</b>

    嵌入式技術:STM32Cube生態系統介紹#嵌入式系統

    嵌入式生態系統
    學習電子
    發布于 :2022年11月12日 23:59:12

    [3.2.1]--STM32Cube生態系統介紹

    嵌入式微機原理生態系統
    jf_90840116
    發布于 :2022年11月15日 00:35:03

    大數據hadoop生態系統概念簡單介紹

    零基礎大數據入門3--大數據生態系統及其各組件簡介
    發表于 05-05 14:34

    工廠生產系統能效的生態系統優化設計

    優化工廠生產系統能效的生態系統
    發表于 07-12 08:44

    everspin生態系統和制造工藝創新解析

    everspin生態系統和制造工藝創新
    發表于 01-01 07:55

    gpu工作原理是什么?

    gpu工作原理是什么?
    發表于 05-31 06:17

    STM32單片機基礎01——初識 STM32Cube 生態系統 精選資料分享

    本篇文章主要介紹STM32Cube生態系統。STM32Cube EcosystemSTM32Cube是ST公司開發的一套生態系統,致力于使STM32的開發變的更簡單,并且100%開源免費。在開始
    發表于 08-03 07:15

    什么是STM32Cube生態系統

    什么是STM32Cube生態系統
    發表于 09-29 06:12

    GaN功率半導體與高頻生態系統

    GaN功率半導體與高頻生態系統(氮化鎵)
    發表于 06-25 09:38

    STM32Cube生態系統助力開發者釋放創造力

    STM32Cube生態系統,助力開發者釋放創造力,本片文檔主要介紹選型、原型評估、配置、編譯、軟件包、調試、燒錄、監測和總結。
    發表于 09-05 06:10

    GPU服務器的詳細介紹工作原理說明

    眾所周知,GPU是圖形處理器,在很多任務中,GPU占據著重要作用,如深度學習領域。為增進大家對GPU的了解,本文將對GPU服務器加以介紹,并
    的頭像 發表于 11-28 10:01 ?7604次閱讀

    STM32實戰 1 | STM32Cube生態系統認識與介紹

    STM32實戰 1 | STM32Cube生態系統認識與介紹STM32Cube Ecosystem STM生態系統STM32Cube MCU Packages(STM32外設控制)首先介紹
    發表于 11-19 12:36 ?14次下載
    STM32實戰 1 | STM32Cube<b class='flag-5'>生態系統</b>認識與<b class='flag-5'>介紹</b>

    NVIDIA公共cuNumeric將GPU加速超級計算引入NumPy生態系統

      隨著數據集和程序的規模和復雜性不斷增加,人們越來越需要利用計算資源,這遠遠超出了單一 CPU 節點所能提供的功能。 cuNumeric 將 GPU 加速超級計算引入 NumPy 生態系統。下圖顯示了輕松擴展到 1000 GPU
    的頭像 發表于 04-14 14:55 ?1433次閱讀
    NVIDIA公共cuNumeric將<b class='flag-5'>GPU</b>加速超級計算引入NumPy<b class='flag-5'>生態系統</b>中

    GPU和FPGA的工作原理及其區別

      GPU和FPGA都是現代計算機技術中的高性能計算設備,具有不同的特點和應用場景。本文將詳細介紹GPU和FPGA的工作原理及其區別。
    的頭像 發表于 08-06 16:50 ?2799次閱讀
    主站蜘蛛池模板: 天天干天天草 | 人人艹人人艹 | 欧美黄色精品 | 国产成人精品一区 | 国内精品久久久久久久久野战 | 亚洲成在 | 日韩高清毛片 | 91大神免费视频 | 五月丁香啪啪 | 五月丁香啪啪 | 亚洲小视频在线播放 | 国产五月 | 久久精品人 | 久久国产精品久久久久久 | 天天弄 | 狠狠干狠狠干 | 亚洲亚洲人成网站在线观看 | 在线天堂中文官网 | 天天久久影视色香综合网 | 在线观看精品视频看看播放 | 黄色美女网站免费 | 久久国产影视 | 中文在线资源链接天堂 | 伊人久久综合网站 | 丁香婷婷九月 | 成年女人毛片 | 毛片在线网| 国产精品免费看久久久 | 国内久久精品视频 | 163黄页网又粗又长又舒服 | 国产一级一级片 | 久久综合五月婷婷 | 日本不卡1 | 欧美日韩一区二区不卡 | 少妇被按摩 | 天天做天天爱天天爽综合网 | 色视频网 | 久久88色综合色鬼 | 新四虎影院 | 久操视频在线 | 欧美.成人.综合在线 |