返回列表 发帖

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

http://pc.watch.impress.co.jp/docs/2005/0713/kaigai198.htm5 z* t. t/ V8 `% w6 d8 n  U! t& `
1 `  y1 A, v- W; p) S- T! c& Z
這篇有個有趣的地方,就是第一個R520確實的spec出現了:
/ B; T7 z6 C. p128 way multi-thread。* y1 x8 R# t- q# Z( ~
同樣的算法是C1 (64threads) 的兩倍。, o& V3 s& F) }
" I0 w) B+ i# T4 {$ p
這有兩個方向:% P! S) n- s2 k7 I# K
/ g3 E( F/ U7 H) |. Z7 J( ]
1. 和C1同樣2 r  Q0 }3 F$ T8 \% x9 a
16ALU per bank,然後兩倍大(6bank?), v, n+ l2 H: ?3 D2 s- `
, E" h7 P( X0 s- x
2. 每個bank小很多,6 g# g. G$ N  d4 n
所以每個bank可以要在更多thread之間跳," f1 H6 w9 O" h; H. X
用來爭取效率。9 f) I4 G$ U( G- W( A5 ?5 N
- @  i5 k7 D: v
; q6 ~. u5 j( i
G70 与 R520、下一世代的GPU将Multi-threading列为标准9 O& q. A! ~" F5 i* s

- l% H; K% z' b' k9 Z3 Y' {4 Q> NV40/G70视Shader种类而实作不同的Multi-threading。% u2 Y  e9 x2 Z# W4 c3 q, X
, D: x" H: X& B* K! {, b$ [( }
目前已知有Multi-Threading的GPU,NVIDIA有NV40系列、G70系列、还有PS3所装载的RSX。" m$ q" S/ H. l" ]. ^
ATI的化则有次世代GPU的R520。不过Multi-threading并不是GPU两强的独占技术,而是整个业界的趋势。比方说S3 Graphics的次世代产品「Destination」等,也提到会实装类似的Multi-threading技术。看来,未来的GPU而言Multi-threading将会成为标准功能吧。7 h( I3 O8 I. p5 o
1 }( x2 q# c+ P0 O* P, ^5 ]
至于各公司又如何实作这个功能呢?
' @" r6 w4 G$ H) P2 J- F# t5 R" b$ S* C" Q$ U$ ^
由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应该也是相同。
& V) r# C3 N& ?8 |% m9 F! O+ [/ ^0 }% B
而根据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先生则做了下列的说明。! \( k5 C" c; g
# t" I$ I- A( O3 L' K2 q
「Shader在对每个pixel执行过指令1后,会对别的pixel执行指令1。也就是说,对一开始的第一个pixel执行指令2,有可能是在100个cycle之后的事情了。」% X% n+ `$ w7 e
& b! W2 I' ]0 K1 w
常识上来说,比VS还要有更多texture fetch的PS,理所当然会在更多的thread间做平行处理。NV40/G70的Pixel shader实际上到底有多少的平行度并不清楚,但是应该至少比VS的平行度更宽广。4 ]2 I8 `6 G" {- B6 a$ d) B! ^
' B2 ]+ g5 {4 L7 H" E6 I

, f4 `9 t9 `$ k# m
# R8 Y& z" Y" X, {, p> 对Unified Shader进行Multi-threading的ATI7 b' j% l8 K, @, S

* v7 _9 i* t! A由于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)
# C  F0 K5 e- j$ i1 k0 `* V1 W0 l/ f; f7 s9 w3 `
从Feldstein先生的说法,48个XBox360的Shader,每16个分成一个群组,并且以threading来控制。「我们将处理器每16个分成一个单元,共分割成三个。并且每个单元(16个shader)各自执行不同的thread。所以(没有进行threading变换)的状况下,即使有一个单元停滞了,另外两个thread、32个shader仍然会继续动作。」Feldstein先生如是说。, V: j. E& {/ k8 t7 [

0 h. B! C. z2 q* v+ P' Z* S也就是说,每个单元(16 shader)共执行三个threrad,然后可以在共计64个thread上切换。在这边虽然对NVIDIA与ATI两家公司彼此的「对thread的定义」是否相同抱持着疑问,但是至少可以知道,ATI也有宽广的平行度。
' C: \+ R5 \7 P
1 ?- J6 q' z$ |( d5 Z' C* Y
9 Y# R" S2 Q7 [' q; g1 W6 P8 s9 i+ c8 }& o$ x! F9 q
此外,ATI的PC用新GPU R520,能进行总共128way的 Multi-threading。也就是说,它能够控制Xbox 360约两倍的thread。由某位PC业界人士所说,ATI对顾客表示R520的结构上Multi-threading是非常重要的部份。+ r5 O2 ?; n8 I
1 b4 k4 S- g, Z& R$ @# r
其它GPU厂商的Multi-threading的部分虽然都还不清楚,但是到了Unified-Shader世代之后,应该所有厂商都会使用Multi-threading。由与GPU相关的情报来源指出,某个GPU厂商,将Unified Shader里面的每个Shader都设置了 thread queue,并且在每个queue之中存放了多个thread的stage,然后在thread之间切换。也就是说,通常都是每个shader各自分配到一个thread,然后做multi-threading(切换),是一般的控制方法。; V2 u  b& C7 _
2 S6 f; u, U  E3 H8 [6 w" o
> 将SRAM分散到各个Shader,来作为state的保存
7 A- E! }5 C3 p0 [
+ J$ o7 E" `/ Z9 T$ d9 m9 i2 A, EGPU整体来说大约有数十到上百的多thread。如果是CPU的话,各个CPU能做的Multi-thread也不过是每core约2way~4way的程度,相对于CPU而言,GPU做的Multi-threading的平行度都要大得多。2 Y. l8 A& q* k% n; C
# g3 f8 o. U  N' B) U- G# r
不过,不可避免地总是要做取舍。为了处理作业中的thread,各个thread的的stage(如Register file与各种控制的现况)都必须保存下来。* i3 v4 P5 Z/ y( c2 E( Z( w
  p, ~' D0 J9 o, M2 r9 Y6 j
「各个pixel thread在做完shading之前,所有必要的state都需要在芯片内储存起来。有几个pixel,就会有几个thread要保存。」Kirk先生如是说。( s: B$ ]! S+ E% J) m* K& d' X

, g$ ]# }  P/ M5 _为此,想要实作宽广的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)
) k' i  M" `( c8 y! }" F5 Q+ O% }7 P$ h; V2 t& ]. B% v- x
*:过去曾经引用过内文0 F- r1 }9 v  ^$ [' R8 ]: }
* w3 F3 c4 Z4 X  R4 J
不过,NVIDIA的Kirk先生表示,对GPU来说,即使这样(Multi-threading)仍然值得采用。
6 u0 p' L$ H' u% I8 R5 Z4 ~% V3 ]5 c* {2 x1 `
「NV40有着大量的晶体管。GPU Shader的结构上,不需要存在像是CPU那样极为庞大的Cache。所以可以将(本来会使用在Cache上的份量)的海量存储器,分散配置到管在线。而透过分散配置的内存来保持state内容,来确保Shader Core不会stall、而能够持续维持有效率的运作。
' p* g" H& N9 D  ~- W: H/ }7 z
* u7 e! ]/ m0 e7 L2 ]现在的CPU可能有几个MB等级的cache,但是GPU的cache并没有那么大。反过来说,由于将SRAM分散配置到流水线的许多个地方,并透过SRAM来储存state,来实现相当大量的multi-threading。也就是说,可以选择把SRAM分配在Cache容量上,来提高Cache的hit rate、减少存取DRAM的机会;或者把是SRAM拿来储存thread的state、提高thread的平行度,来隐藏存取内存的延迟,防止stall.... 整理起来就会像下面这样:
' _5 U6 }+ B5 y, o0 |5 c: t  A" J9 l$ V1 h# r* S
CPU--大容量SRAM用在Cache--Cache hitrate提高--减少DRAM存取--减少stall  W% V) y% g/ ]( U) Q3 l
GPU--大容量SRAM用在维持state--thread平行度提高--DRAM存取延迟的隐蔽--减少stall/ I  m6 H' u  K/ B1 z/ [0 j

2 O+ P5 F) ^, O6 n3 g! d1 d7 {2 |) f所以,针对必然发生的cache miss来设计的GPU,实作的方向很明显地会趋向后者。
- H, P& z0 T/ ?2 u) ^# x0 {$ x6 ]; P$ k9 U% k% K7 t
> GPU的 state 内容维持1 y+ T  A" n  C( G# l
; T; \' b/ r5 |$ {
说起来,GPU到底将哪些state用怎样的形式来保存起来,并没有被公开。CPU的状况就狠单纯地,将生成thread的母程序所占有的内存空间,整个thread持有的数据state与控制state都加以复制。4way multithread的话,就会维持完整的四份register file。! o7 d6 T  h9 V# P
  `7 d% K$ S8 H, }
但是,向GPU这样的stream processor的话,有可能有不同的设计方法。比方说,史丹佛大学的Dally先生研究的Stream Processor的状况,就是将Register File透过阶层化的方式来管理。- p- U/ Q6 b* O3 @- \
1 J7 j+ R) y+ U/ Z
而且,GPU的Register结构和CPU有很大的差异。以逻辑上来说,Shader有Temp、Input、Output的Register,以及Constant Register、Instruction Slot等。其中,以Temp、Input、Output这三个是每个Thread独立的。1 `: p/ g4 E; G+ u1 }
4 E3 _2 E8 e6 i2 f9 V' O
存放指令slot的物理内存,是存放Shader Program的地方,以Shader来说不见得会有I-cache(当然也是有可能有),而也有可能是存放在内存上。虽然有许多种不同的Stream Processor存在,不过GPU大部分的状况是程序固定而数据不同、也就是Program(Shader code)固定、而处理的不同数据(pixel or vertex)较多的状态。所以Instruction RAM不会随着处理的pixel、vertex不同而切换,或者也有可能是Shader之间共享同一份内存。
: }) O- x" }  ~6 D7 i
) s: b+ H3 R5 a) O( Y; i2 F这部份的控制方法、state的保存方法都还没有被详细提及。
, V$ k3 p' W# `2 y6 H$ Q0 k* G' g, D$ x7 R
> GPU 是采用细单位的threading4 h$ n% m: Y+ s, ]& k

$ M* k8 m$ R# E( @' nMulti-threading的控制法有下列几个方法:
+ V' k9 K7 g4 K0 @2 V  u+ f$ t8 z* a7 s+ J
SMT(Simultaneous Multi-threading)
1 b  k$ P5 ^# [6 O, |3 sFine-Grained Multi-threading8 k5 ^. n7 \1 M3 c
Coarse-Grained Multi-threading% \7 `6 O5 B0 U
& \) h( `3 v6 y6 V5 K
SMT是类似Pentium-4的Hyper Threading那样,在同一个cycle内可以执行不只一个的指令的结构。并不是切换thread,而是可以同时执行完全不同的两个thread。
  z' D) ?& [& v8 n; F7 t6 R- d1 R8 t4 ~, ^
相比之下,Fine-Grained Multi-threading则不会在一个cycle里面同时执行两个指令。而是可以以cycle为单位切换执行不同的thread。Cell 的 PPE 的Multi-threading属于这种结构。
2 w/ y, K- A$ G0 D! J; V& Z) J% e4 S
Crarse-Grained Multi-threading的话,只支持用更大的来切换thread。没办法在每个cycle里面切换thread,而只有在延迟相当大的事件发生时,才会切换thread。虽然切换thread本身也会有一定程度的延迟,但是至少会比将context switch回内存要来得快。1 d0 i$ d7 V( r( t, H5 w8 F
+ R; y( P) M/ o' e! z
至于GPU所采用的,全部都是Fine-Grained Multi-threading。, E* f7 I% Y5 d5 n/ s. ^5 D0 M
: `' p, v  y1 D" G  ]7 U
「NV40的threading是Fine-Grained Multi-threading」(Kirk)/ |! Z! k* w7 k! A$ S
「(XBox360 GPU)以小单位来做threading,可以在每个cycle切换thread。」(Feldstein)- b+ e5 R2 ^$ x( c* W) s
) W1 M/ w/ k+ n( \3 s& C
SMT对计算资源的利用虽然有效,但是控制相当复杂,而且如果计算资源本身的平行化不足的话就没有意义。如果只是为了隐藏内存存取的延迟,Fine-Grained Multi-threading已经相当有效。) A  T' C8 k. U- a, c
/ N* U8 x9 u2 K* y2 U9 i. F
> 如何触发thread切换- p8 o# _$ Y9 c' ~2 a5 s0 ^: O" k
2 E$ G& ]0 {; H. ~/ }& c
基本上,实际上的threading的话,应该会在发生较长延迟的状况才会进袭。' _# n; A$ L) {$ [1 A# Z! R3 v' f

1 h8 o' L3 y7 b; B2 P2 P「包含Texture cache miss在内,有很多状况都会触发thread切换。某个thread在遇到阻碍它执行完毕的因素之前会执行到结束。在阻碍执行的因素里面,可能包含了cache miss、或者是需要的资源目前被其它的thread占用之类,有可能遇到很多种状况。条件分支也可能造成stall与thread切换。因为所需的数据是不是在cache里面,是受到分支的区域性来影响的。」(Kirk). R$ _- K- u/ u& H
( B; j& t: ?% d' }
ATI也表示朝内存存取Texture的动作会启动threading,可是「分支(方向)执行错误(而stall)的状况,不会更换成其它thread。」(Robert先生)。可以看出在thread的上仍然有些落差。7 V. j8 Z4 u5 H& n9 C
. f2 ~3 ~, _# N$ X& w
此外,Shader program也和CPU上的program一样,都会进行比方说尽早提出Texture load之类的最佳化方法,来帮助隐藏内存存取延迟。Multi-threading乍看之下是与指令层级的静态排程(scheduling)结合,但是并非如此。推测应该是与CPU一样基本上在cache hit的时候以排程隐蔽较小的延迟,而在cache miss的时候透过multi-threading来隐蔽较大的延迟。$ ]/ n" m; q6 M' n8 d
( L: A& ~# c. l! V# ?
静态的排程与多执行绪的关系,其实与CPU是一样的。以IA-64为例,IA-64透过compiler,将load、store、还有分支之类的指令都往前排的手法,透过指令排程来隐蔽内存延迟。可是在此同时 Montecito 还引入了 Coarse-Grained multitheading,在发生更长的延迟的时候会进一步来切换thread。
3 X. e% i$ V, K: T( I6 z* N" h; {5 E% R4 e+ R9 _
Shader的Multi-thread举例6 s1 E4 a2 N% }/ W- {$ ?; x
8 c! z7 ?. J# C( ?! Q* J
: B- V) W8 u/ h2 K
为了处理内存的延迟而朝multi-thread前进的GPU。由于Multi-thread会成为影响Shader效率的重要关键,而被视为未来GPU效率的重大影响因素。GPU的性能越来越不再是只单纯地受到流水线数量、Shader数量或是时脉等的因素影响,而越来越难以判断了。比方说,即使说「理论效能OOGFLOPS」有高有低,实际上因为Multi-thread之类的Shader控制结构的不同会影响效率的原因,实际上的性能高下可能又是另外一回事了。
“They’re the world’s leading designers and manufacturers of CPUs – how hard could it be to build a GPU? I mean, come on, how hard could it be? That crummy little company down the road builds them – we could build them in our sleep. Come on, how hard could it be?” ——NVIDIA David Kirk

不太懂,有些问题请指教。/ A9 t0 E- r. |+ c
如果一段PS代码里使用了Texture A,编译器会创建另外一个thread,在VS代码执行的时候就把A提前load进来?
* B. V4 y# W  z6 }7 V: f8 b; m驱动是怎么给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 发表! s8 U) t0 ]. F0 ~) R1 l: ]+ c, f
GPU流水线式作业, 不可能说先执行VS, 等VS执行完了再执行PS之类。所有的VS, PS分别执行同一段shader, 以MIMD或者SIMD的方式. 但就算是MIMD的方式, 也是同一代码, 不同分支而已. GPU的thread仅仅是硬件处理以隐藏数 ...
- Y! f& m' y7 y% y5 }+ ]8 |
先感谢你的回复。! @- ~+ M/ A' l8 K2 m6 }
对,GPU都是流水线式作业,现在我理解了,以前想岔了。GPU的MultiThread只是一个Thread如果需要等待就切换到另外的Thread执行,不要干等。
# h1 u9 A( Q4 R$ f9 L5 X不过我觉得还是应该有个调度问题,比如调用一个DrawPrimitive()就只渲染一个三角形,也要每个VS单元都执行?每个VS单元能执行的最小粒度应该是一个三角形。如果只有一个三角形选一个执行,其他的VS单元空着,如果有多个三角形,平均分到不同的VS单元执行?是这样吗?( W" J2 {2 M2 {- N, L
还有SIMD的结构如何执行条件语句了?
8 J8 `/ U' v7 G) f我问的问题可能有点初级,还希望各位多多指教。谢谢。( t$ _5 A7 a/ L, j+ D7 M3 k1 X) s
1 k9 Y% e. K1 x# t
[ 本帖最后由 chena_cpp 于 2006-8-19 01:17 编辑 ]

TOP

VS执行的是单位是Vertex, Triangle属于Setup单元的工作(Setup目前应该是一个串行的部件). 三个Vertex可以使用三个VS单元来做, 至于其他的VS在做什么, 无所谓; 反正不影响结果就行. 不过要发挥GPU的性能, 产品级的代码没有人会这样做. 比如XBox360的C1, Thread执行单位是64个Vertex或者Pixel.: F) `$ a8 L0 H) F) X9 M9 f6 Q
$ q* [4 h1 u/ S6 S& {$ y6 Z; }7 m
SIMD有一个Thread block, 这个SM3出来的时候应该已经讨论得够多了...

TOP

原帖由 chena_cpp 于 2006-8-17 20:40 发表% y* Y/ b, u4 ]
不太懂,有些问题请指教。2 k, J: {! l- W0 s% w/ L2 k
如果一段PS代码里使用了Texture A,编译器会创建另外一个thread,在VS代码执行的时候就把A提前load进来?0 f* x# j0 P0 ?' x* n$ R# B
驱动是怎么给VS,PS单元分配任务的?比如我现在调一个SetVertexShader(),会 ...

; M6 r/ b$ J4 z/ x3 Z) ~8 n! \; W5 a4 f/ t$ e& @1 \. M
要看你前面的代码,自己看看DX文档吧,我去年学的都忘了
; u8 x( q$ s, O2 @2 o  C+ `这里研究编程的很少,这种问题可以去CSDN:sweatingbullets:

TOP

原帖由 RacingPHT 于 2006-8-19 13:16 发表
1 M7 j' Q; e8 x) }' n( D6 ]5 J7 mVS执行的是单位是Vertex, Triangle属于Setup单元的工作(Setup目前应该是一个串行的部件). 三个Vertex可以使用三个VS单元来做, 至于其他的VS在做什么, 无所谓; 反正不影响结果就行. 不过要发挥GPU的性能, 产品级的 ...

* ^( X; P" \/ D" c- _谢谢。

TOP

原帖由 Prometheas 于 2006-8-19 17:17 发表& b* p' J. C6 I  D/ b

+ u+ C( e- E' M7 [4 Y5 \2 m: y, @5 i4 f3 r. C
要看你前面的代码,自己看看DX文档吧,我去年学的都忘了
- Y, A8 q. }  u1 k这里研究编程的很少,这种问题可以去CSDN:sweatingbullets:

4 U; ~  w9 S2 j' r$ j2 IDX的文档没说这个问题吧。

TOP

原帖由 Prometheas 于 2006-8-19 17:17 发表1 o. K3 _8 W7 z, I
% s' K4 o( L. O. s; v8 t2 s; r2 p
% H: X9 M: A, G- k2 G( ]
要看你前面的代码,自己看看DX文档吧,我去年学的都忘了! ]/ _  g* N6 I- I+ J& ^8 q
这里研究编程的很少,这种问题可以去CSDN:sweatingbullets:
5 k/ h& s5 [4 Z
这个东西不是DX能够控制的

TOP

原帖由 ayanamei 于 2006-8-20 00:08 发表
" {( \6 p. {( w$ ^' m# L$ H+ I4 i1 \' p( q# ^2 p$ j
这个东西不是DX能够控制的

3 Y4 g8 T& e5 [4 J+ Z& Y7 H; K2 L6 m8 ]( F! p
(_(DX9 HLSL中需要指定VS和PS版本,就像Cg的Profile一样1 e$ ]+ @- C, H5 o
, a$ W8 m. L4 Q
:sweatingbullets:可怜的Cg现在只能用于PS2了

TOP

Cg很早就已经可以用DX 9.0c,指定ps3/vs3 profile。
“They’re the world’s leading designers and manufacturers of CPUs – how hard could it be to build a GPU? I mean, come on, how hard could it be? That crummy little company down the road builds them – we could build them in our sleep. Come on, how hard could it be?” ——NVIDIA David Kirk

TOP

原帖由 Prometheas 于 2006-8-20 00:12 发表
! |  X1 z0 e, L6 A6 V; `' H0 _' _6 G- A. G  [# r
, k" f" s3 l$ x3 v6 m
(_(DX9 HLSL中需要指定VS和PS版本,就像Cg的Profile一样
7 l% e' @9 ~: X* T$ L! g, p! p+ m0 A/ V$ X+ w
:sweatingbullets:可怜的Cg现在只能用于PS2了

8 r6 G! c6 K* c3 b5 z: P上面说的是具体操作GPU thread情况吧?

TOP

返回列表