返回列表 发帖

PCWatch) G70 & R520等次世代GPU、將Multi-threadin標準化 翻译 by eji

http://pc.watch.impress.co.jp/docs/2005/0713/kaigai198.htm: \' W/ l' ~6 Z5 c* x; z- s; j7 c

/ Z9 J8 O6 I! O! f! q0 O這篇有個有趣的地方,就是第一個R520確實的spec出現了:: {4 R7 Z  S* t/ E( k
128 way multi-thread。7 T' o. ^$ {; |2 L9 y% F: i. {
同樣的算法是C1 (64threads) 的兩倍。6 l4 K7 p/ {3 V+ [& H. }  G2 W
0 o6 h5 z3 r( a
這有兩個方向:
. y" e" t  ]  v! {5 z) j4 ?% x2 g
3 Q. {3 P2 N. F6 k+ h1. 和C1同樣: s3 j, }& A4 K: w1 P' a9 V5 j' U
16ALU per bank,然後兩倍大(6bank?)+ D. J( G1 [: t
; u, @! w6 Z+ ]5 x- q/ a/ \
2. 每個bank小很多,5 b; L- U% _! A7 N' Y3 g
所以每個bank可以要在更多thread之間跳,% x/ G" N+ K9 N/ x" m0 k
用來爭取效率。  H# v  L/ a& A5 c$ D4 x0 j  F9 g" N

# X+ y$ [0 g$ S+ D2 X% S' x) Q7 ~) e
G70 与 R520、下一世代的GPU将Multi-threading列为标准) j) N! ]; p+ X
+ q' C3 L0 M7 h
> NV40/G70视Shader种类而实作不同的Multi-threading。' e6 A& P2 N9 ]% b. }0 S
7 w, D3 t, o7 e" ]3 ]
目前已知有Multi-Threading的GPU,NVIDIA有NV40系列、G70系列、还有PS3所装载的RSX。, \* c! h: o% S& z9 M' b
ATI的化则有次世代GPU的R520。不过Multi-threading并不是GPU两强的独占技术,而是整个业界的趋势。比方说S3 Graphics的次世代产品「Destination」等,也提到会实装类似的Multi-threading技术。看来,未来的GPU而言Multi-threading将会成为标准功能吧。
! }1 q7 V& L2 Q) \6 s% E  q* F' q1 e+ [) u6 e
至于各公司又如何实作这个功能呢?! \  Y/ G! F0 E+ F6 @0 f
) V0 d1 p6 r8 p# R6 C: a( {1 ^
由NVIDIA的GPU结构设计师John Montrym去年夏天于HotChips的简报所提到的数据,NV40的VS每个单元可以有最大3个thread实行的能力。NVIDIA的David B. Kirk针对这部份(每个VS有3way的 multi-threading)也是直接肯定了这个部份。NV40有6个VS,就是共计18threads。而且据Kirk先生所说,G70与NV40在这方面是相同的,所以RSX应该也是相同。  ]5 b+ N6 ]7 C: D/ }& c% [& Y
7 d$ v7 A4 A8 ~) H
而根据Kirk先生所说,NV40的PS也进行了Multi-threading。可是到底有能够处理多少数量的thread则没有明确公布出来。NVIDIA的论文(「The GeForce 6800」,John Montrym & Henry Moreton, IEEE MICRO MARCH-APRIL 2005)则提到「为了隐藏对存取外部内存而带来的延迟,各个Fragment Processor(PS)能够维持住100个in-flight thread(正在执行的thread)的stage(信息)」。而在去年秋天的访谈中,Kirk先生则做了下列的说明。6 }8 R( c/ f5 T+ ]
9 {; |% q' k% _: ^0 g8 d  v
「Shader在对每个pixel执行过指令1后,会对别的pixel执行指令1。也就是说,对一开始的第一个pixel执行指令2,有可能是在100个cycle之后的事情了。」& ]/ y, r; W  i; }0 G7 C# \& c
9 S$ A, A! D9 g; g7 N+ Y
常识上来说,比VS还要有更多texture fetch的PS,理所当然会在更多的thread间做平行处理。NV40/G70的Pixel shader实际上到底有多少的平行度并不清楚,但是应该至少比VS的平行度更宽广。7 x3 d9 m6 F- v: k; N
* v, o5 n7 {. R0 l2 R! b

( g! C) N. @% R" D9 r" A% c1 s% T% j# W; Z; x
> 对Unified Shader进行Multi-threading的ATI- A$ C6 L0 H* H- r- V  [0 t
- u8 ^2 J. {% F  O+ k
由于ATI开发的XBox360GPU是Unified Shader结构的关系,并没有VS与PS的分别。XBOX360的Shader全部总共可以控制64个in-flight thread。「我们在芯片里面准备了state buffer。所以可以on-the-fly 切换64个thread。」(Robert Feldstein、ATI Technologies, Vice President - Engineering)6 t+ w3 S0 ]/ L, Y
. ]" v& ]3 W; D+ G6 ]. v5 x/ b! q
从Feldstein先生的说法,48个XBox360的Shader,每16个分成一个群组,并且以threading来控制。「我们将处理器每16个分成一个单元,共分割成三个。并且每个单元(16个shader)各自执行不同的thread。所以(没有进行threading变换)的状况下,即使有一个单元停滞了,另外两个thread、32个shader仍然会继续动作。」Feldstein先生如是说。" [* z5 {4 F/ h6 S% f7 ~/ T
+ z& c' E) j$ ]$ W+ D( s
也就是说,每个单元(16 shader)共执行三个threrad,然后可以在共计64个thread上切换。在这边虽然对NVIDIA与ATI两家公司彼此的「对thread的定义」是否相同抱持着疑问,但是至少可以知道,ATI也有宽广的平行度。3 k2 z. ^0 e* M$ b; M( \
2 A5 H/ g3 _- \( M
* q2 P! f  w1 T1 Y) X
/ n- y3 ]! K6 _7 D3 _" W5 W5 ~
此外,ATI的PC用新GPU R520,能进行总共128way的 Multi-threading。也就是说,它能够控制Xbox 360约两倍的thread。由某位PC业界人士所说,ATI对顾客表示R520的结构上Multi-threading是非常重要的部份。6 g6 H' b5 l6 U) t' i# z% h7 i3 O  p
8 F) Z1 `' \3 U7 x" A: d
其它GPU厂商的Multi-threading的部分虽然都还不清楚,但是到了Unified-Shader世代之后,应该所有厂商都会使用Multi-threading。由与GPU相关的情报来源指出,某个GPU厂商,将Unified Shader里面的每个Shader都设置了 thread queue,并且在每个queue之中存放了多个thread的stage,然后在thread之间切换。也就是说,通常都是每个shader各自分配到一个thread,然后做multi-threading(切换),是一般的控制方法。5 `9 `5 s. H6 W, e2 T' P" c
) D5 B  E- C2 {1 C: [
> 将SRAM分散到各个Shader,来作为state的保存# R7 }. s* h4 z1 F4 Z

$ N) U+ n; F( C* N; i# ~GPU整体来说大约有数十到上百的多thread。如果是CPU的话,各个CPU能做的Multi-thread也不过是每core约2way~4way的程度,相对于CPU而言,GPU做的Multi-threading的平行度都要大得多。% G! F7 q0 ~" O1 d/ V  q- d3 d
) X, g; V9 Q( @7 a
不过,不可避免地总是要做取舍。为了处理作业中的thread,各个thread的的stage(如Register file与各种控制的现况)都必须保存下来。% h* ^$ i$ O( _  l. `, v

+ p! t& c9 }/ R% l5 V- {! H「各个pixel thread在做完shading之前,所有必要的state都需要在芯片内储存起来。有几个pixel,就会有几个thread要保存。」Kirk先生如是说。
& W5 W. k) u( {: b/ G5 _. e2 j/ T7 Q" c% D! b, _
为此,想要实作宽广的Multi-threading,等于就需要更多的晶体管数(芯片面积)。2004年8月召开的GPU通用运算会议(GP2),史丹佛大学的Bill Dally先生(Computer Systems Laboratory, Stanford University)提到这个问题时说。Multi-threading由于必须保存所有的state信息,成本非常地高昂。(「Stream Processors vs. GPUs」, Bill Dally, GP2, August 8, 2004)
% p; ]$ P4 l2 @' X- c# M9 F8 d$ J' x  @6 T6 e! i. L6 a+ p
*:过去曾经引用过内文/ H& |( l5 _$ O, x' S/ ~; A( F
, o  S$ D. e$ J+ j0 w* }( l; j' b
不过,NVIDIA的Kirk先生表示,对GPU来说,即使这样(Multi-threading)仍然值得采用。6 B" t$ d- I7 r: e2 h4 [
) O" C1 x' H/ p3 ?! p
「NV40有着大量的晶体管。GPU Shader的结构上,不需要存在像是CPU那样极为庞大的Cache。所以可以将(本来会使用在Cache上的份量)的海量存储器,分散配置到管在线。而透过分散配置的内存来保持state内容,来确保Shader Core不会stall、而能够持续维持有效率的运作。
  I) @+ _( B+ R  b, o! i2 j; w
/ f. \. Q/ o0 M$ b: T* `- y现在的CPU可能有几个MB等级的cache,但是GPU的cache并没有那么大。反过来说,由于将SRAM分散配置到流水线的许多个地方,并透过SRAM来储存state,来实现相当大量的multi-threading。也就是说,可以选择把SRAM分配在Cache容量上,来提高Cache的hit rate、减少存取DRAM的机会;或者把是SRAM拿来储存thread的state、提高thread的平行度,来隐藏存取内存的延迟,防止stall.... 整理起来就会像下面这样:5 v; N9 {( C$ l  [' N! y9 I8 c& F
# o$ \/ F' k2 r0 V( v9 X
CPU--大容量SRAM用在Cache--Cache hitrate提高--减少DRAM存取--减少stall* @8 C4 @& {: o* B, Q
GPU--大容量SRAM用在维持state--thread平行度提高--DRAM存取延迟的隐蔽--减少stall& s. m2 X. K, N3 N! \6 G) \
7 J+ p; K" ~2 L* n2 n0 i/ E
所以,针对必然发生的cache miss来设计的GPU,实作的方向很明显地会趋向后者。
2 Z" l1 ~7 _9 N2 Y  q2 w7 i4 e' _& U8 k4 J8 V$ \+ q
> GPU的 state 内容维持: N7 j8 X& w8 _/ o) f4 ~  n
% i& b1 [2 p7 M7 t( d
说起来,GPU到底将哪些state用怎样的形式来保存起来,并没有被公开。CPU的状况就狠单纯地,将生成thread的母程序所占有的内存空间,整个thread持有的数据state与控制state都加以复制。4way multithread的话,就会维持完整的四份register file。
7 T* y1 q% [, X( s4 l  y- r4 \) O8 S4 {. I
但是,向GPU这样的stream processor的话,有可能有不同的设计方法。比方说,史丹佛大学的Dally先生研究的Stream Processor的状况,就是将Register File透过阶层化的方式来管理。
+ W$ o3 H! C/ i0 J: H& z% A5 c( ]+ W$ e  @
而且,GPU的Register结构和CPU有很大的差异。以逻辑上来说,Shader有Temp、Input、Output的Register,以及Constant Register、Instruction Slot等。其中,以Temp、Input、Output这三个是每个Thread独立的。) T8 {: e1 I/ `. S* j% y& S
; H$ \! r; P( ~, Q/ z5 k
存放指令slot的物理内存,是存放Shader Program的地方,以Shader来说不见得会有I-cache(当然也是有可能有),而也有可能是存放在内存上。虽然有许多种不同的Stream Processor存在,不过GPU大部分的状况是程序固定而数据不同、也就是Program(Shader code)固定、而处理的不同数据(pixel or vertex)较多的状态。所以Instruction RAM不会随着处理的pixel、vertex不同而切换,或者也有可能是Shader之间共享同一份内存。
; v+ a. ]3 \& A. |, b- O$ O, Z3 I  s- V
这部份的控制方法、state的保存方法都还没有被详细提及。$ A. m* G  G1 K

) }) u- V" o) q5 `4 d1 n> GPU 是采用细单位的threading
8 G4 ]& U  c! F- ~/ I- v$ U4 C! z3 u
Multi-threading的控制法有下列几个方法:# {- U; H$ F0 G5 [( q, F
1 t/ C4 ~, L) {
SMT(Simultaneous Multi-threading)& k, d  [- k$ W3 F
Fine-Grained Multi-threading
5 W7 N! C& [, U/ p+ m( bCoarse-Grained Multi-threading4 I% i7 i+ g+ c( q$ i) Q% h) Q% `
* D+ U% W, {+ o+ k) \7 ]
SMT是类似Pentium-4的Hyper Threading那样,在同一个cycle内可以执行不只一个的指令的结构。并不是切换thread,而是可以同时执行完全不同的两个thread。3 l  {6 p4 u4 {6 N1 P
: J  N3 ^5 [; G; E1 k' R
相比之下,Fine-Grained Multi-threading则不会在一个cycle里面同时执行两个指令。而是可以以cycle为单位切换执行不同的thread。Cell 的 PPE 的Multi-threading属于这种结构。! N# g" C$ o# Z1 L! D
, i: _8 ]1 s2 I, Z1 C
Crarse-Grained Multi-threading的话,只支持用更大的来切换thread。没办法在每个cycle里面切换thread,而只有在延迟相当大的事件发生时,才会切换thread。虽然切换thread本身也会有一定程度的延迟,但是至少会比将context switch回内存要来得快。
3 y9 c! k4 G8 }3 w: y
6 l# H/ u- @6 M0 O& V  y至于GPU所采用的,全部都是Fine-Grained Multi-threading。
4 L( O; {8 e' z( l- z7 x* d- V4 g. F0 Z7 ]5 i0 N; N# _
「NV40的threading是Fine-Grained Multi-threading」(Kirk)$ ~; o6 z7 f1 D7 ^* u/ U
「(XBox360 GPU)以小单位来做threading,可以在每个cycle切换thread。」(Feldstein)+ e( T/ Y) l2 y7 o, C0 E! \2 M
: E" c3 \0 j' i% l, K6 X
SMT对计算资源的利用虽然有效,但是控制相当复杂,而且如果计算资源本身的平行化不足的话就没有意义。如果只是为了隐藏内存存取的延迟,Fine-Grained Multi-threading已经相当有效。
! S* t$ i# |, K8 m0 J, L: p8 ]2 b9 P8 F5 d/ y
> 如何触发thread切换% o3 r1 K( @. x: E
) v8 u! N/ I/ N; O! @' G
基本上,实际上的threading的话,应该会在发生较长延迟的状况才会进袭。' s  g/ a) \* ]1 S; Q5 O2 H
3 }' Y8 G. P' f  ~: `* |5 T
「包含Texture cache miss在内,有很多状况都会触发thread切换。某个thread在遇到阻碍它执行完毕的因素之前会执行到结束。在阻碍执行的因素里面,可能包含了cache miss、或者是需要的资源目前被其它的thread占用之类,有可能遇到很多种状况。条件分支也可能造成stall与thread切换。因为所需的数据是不是在cache里面,是受到分支的区域性来影响的。」(Kirk)" o0 {$ n0 B" ?& y8 s+ t
3 n9 u2 I& Y0 N4 W5 h  l
ATI也表示朝内存存取Texture的动作会启动threading,可是「分支(方向)执行错误(而stall)的状况,不会更换成其它thread。」(Robert先生)。可以看出在thread的上仍然有些落差。2 E* P1 N1 `; E3 }* h' T8 w+ E
9 }( z0 J+ W# L8 l
此外,Shader program也和CPU上的program一样,都会进行比方说尽早提出Texture load之类的最佳化方法,来帮助隐藏内存存取延迟。Multi-threading乍看之下是与指令层级的静态排程(scheduling)结合,但是并非如此。推测应该是与CPU一样基本上在cache hit的时候以排程隐蔽较小的延迟,而在cache miss的时候透过multi-threading来隐蔽较大的延迟。4 Y# f: U  C6 _+ Q
- b8 j  q: r/ o- S4 a
静态的排程与多执行绪的关系,其实与CPU是一样的。以IA-64为例,IA-64透过compiler,将load、store、还有分支之类的指令都往前排的手法,透过指令排程来隐蔽内存延迟。可是在此同时 Montecito 还引入了 Coarse-Grained multitheading,在发生更长的延迟的时候会进一步来切换thread。
6 E1 ]" |8 p. y4 |0 W$ I2 m; ~' A' `: v3 s2 ~/ }9 O
Shader的Multi-thread举例2 S; s7 Z" u* W( Z* r
2 e5 g" Z3 ^. Q# B/ H, S2 {; ^
3 ?1 B7 v) [$ R7 U: J9 c
为了处理内存的延迟而朝multi-thread前进的GPU。由于Multi-thread会成为影响Shader效率的重要关键,而被视为未来GPU效率的重大影响因素。GPU的性能越来越不再是只单纯地受到流水线数量、Shader数量或是时脉等的因素影响,而越来越难以判断了。比方说,即使说「理论效能OOGFLOPS」有高有低,实际上因为Multi-thread之类的Shader控制结构的不同会影响效率的原因,实际上的性能高下可能又是另外一回事了。

不太懂,有些问题请指教。6 {# X6 d" t6 N/ J2 U+ g' Z
如果一段PS代码里使用了Texture A,编译器会创建另外一个thread,在VS代码执行的时候就把A提前load进来?; L: y7 ~' a2 _8 j% w
驱动是怎么给VS,PS单元分配任务的?比如我现在调一个SetVertexShader(),会在哪个VS单元上执行?

TOP

GPU流水线式作业, 不可能说先执行VS, 等VS执行完了再执行PS之类。所有的VS, PS分别执行同一段shader, 以MIMD或者SIMD的方式. 但就算是MIMD的方式, 也是同一代码, 不同分支而已. GPU的thread仅仅是硬件处理以隐藏数据延迟之用, 而不是CPU thread那样属于OS调度的资源, 独立拥有数据和代码.

TOP

原帖由 RacingPHT 于 2006-8-17 21:40 发表6 o! i" E5 H4 w
GPU流水线式作业, 不可能说先执行VS, 等VS执行完了再执行PS之类。所有的VS, PS分别执行同一段shader, 以MIMD或者SIMD的方式. 但就算是MIMD的方式, 也是同一代码, 不同分支而已. GPU的thread仅仅是硬件处理以隐藏数 ...
) i! \- u0 Q* W# G* W/ W. K2 Y0 |
先感谢你的回复。: m$ X) f$ G# ?- A, }
对,GPU都是流水线式作业,现在我理解了,以前想岔了。GPU的MultiThread只是一个Thread如果需要等待就切换到另外的Thread执行,不要干等。5 r' V3 N+ U$ U; N, u
不过我觉得还是应该有个调度问题,比如调用一个DrawPrimitive()就只渲染一个三角形,也要每个VS单元都执行?每个VS单元能执行的最小粒度应该是一个三角形。如果只有一个三角形选一个执行,其他的VS单元空着,如果有多个三角形,平均分到不同的VS单元执行?是这样吗?4 u, ^7 B2 ^6 w  S0 T* |7 q
还有SIMD的结构如何执行条件语句了?
7 l. c' Y% c: x: ]/ O7 t我问的问题可能有点初级,还希望各位多多指教。谢谢。7 t4 M0 h7 d. e+ F3 F& {
5 l; B8 e2 i) m, j; I) H4 x
[ 本帖最后由 chena_cpp 于 2006-8-19 01:17 编辑 ]

TOP

VS执行的是单位是Vertex, Triangle属于Setup单元的工作(Setup目前应该是一个串行的部件). 三个Vertex可以使用三个VS单元来做, 至于其他的VS在做什么, 无所谓; 反正不影响结果就行. 不过要发挥GPU的性能, 产品级的代码没有人会这样做. 比如XBox360的C1, Thread执行单位是64个Vertex或者Pixel.7 y9 \+ C3 @) w& [
+ w9 W& Z+ f8 N; c$ R/ H
SIMD有一个Thread block, 这个SM3出来的时候应该已经讨论得够多了...

TOP

原帖由 chena_cpp 于 2006-8-17 20:40 发表2 Y: a0 ^9 A: O) o
不太懂,有些问题请指教。' Z2 X2 [. Y+ v3 ^  d
如果一段PS代码里使用了Texture A,编译器会创建另外一个thread,在VS代码执行的时候就把A提前load进来?1 S! E5 J- y& g+ m4 V% _
驱动是怎么给VS,PS单元分配任务的?比如我现在调一个SetVertexShader(),会 ...
! s8 e5 h  u9 C7 g  U
- ]/ q. |- T+ _6 w* Y; ?$ B0 M
要看你前面的代码,自己看看DX文档吧,我去年学的都忘了. i7 j+ ?+ F( ]
这里研究编程的很少,这种问题可以去CSDN:sweatingbullets:

TOP

原帖由 RacingPHT 于 2006-8-19 13:16 发表! R, f* Y  b# g, [. m3 C
VS执行的是单位是Vertex, Triangle属于Setup单元的工作(Setup目前应该是一个串行的部件). 三个Vertex可以使用三个VS单元来做, 至于其他的VS在做什么, 无所谓; 反正不影响结果就行. 不过要发挥GPU的性能, 产品级的 ...
5 k( Q; }) P  l$ \4 G" [6 |4 x
谢谢。

TOP

原帖由 Prometheas 于 2006-8-19 17:17 发表  a2 I1 X6 f1 Y. C+ Z/ V0 H) }

8 A/ C# E* {+ n/ i0 @3 [2 N( {  i6 Y! f$ Z
要看你前面的代码,自己看看DX文档吧,我去年学的都忘了) Y( f" j+ A/ j; \7 {3 i) K
这里研究编程的很少,这种问题可以去CSDN:sweatingbullets:
! U+ W( x# j! W1 ]. d
DX的文档没说这个问题吧。

TOP

原帖由 Prometheas 于 2006-8-19 17:17 发表1 m: l3 I& z" o  A6 E
/ u$ {. L5 N/ G  S3 W

8 I# F, W: o: z  L& b要看你前面的代码,自己看看DX文档吧,我去年学的都忘了! p! E" I7 r1 R1 x
这里研究编程的很少,这种问题可以去CSDN:sweatingbullets:
4 Q# ~/ @  _+ `) n4 x8 i
这个东西不是DX能够控制的

TOP

原帖由 ayanamei 于 2006-8-20 00:08 发表
% p, }& a! q1 J9 ^& `  E6 ?. c* t1 D  g) |' G2 @4 F! U
这个东西不是DX能够控制的
/ W) U/ Z; r3 D8 _* Y. C
) N- h. i, N' h1 m
(_(DX9 HLSL中需要指定VS和PS版本,就像Cg的Profile一样" @& x, b2 Q' }
: Y7 P( z# I; m, {  C# B
:sweatingbullets:可怜的Cg现在只能用于PS2了

TOP

Cg很早就已经可以用DX 9.0c,指定ps3/vs3 profile。

TOP

原帖由 Prometheas 于 2006-8-20 00:12 发表
' c5 C4 F! Q: c2 m: E6 i7 ?: x9 \7 [. q
- G2 Z  P; N2 W! M1 |# O1 a* a
(_(DX9 HLSL中需要指定VS和PS版本,就像Cg的Profile一样7 N2 l) G! f9 ~/ C, h2 |2 z  Q
- [! }3 W  G# |) J+ u$ i
:sweatingbullets:可怜的Cg现在只能用于PS2了

0 f5 Z1 m9 g+ `9 `2 ?上面说的是具体操作GPU thread情况吧?

TOP

返回列表