system
1
显存延迟400-800,大约合计0.5微秒。PCIE不清楚,能有个大致的估计值吗?我猜10-100微秒?应该不会超过1毫秒这个量级吧?
核函数的数据传输,一次传输多大的数据块比较合适?我想传输的时间至少要超过延迟的时间才能比较有效率吧?也就是核函数的流分解到底分解到何种程度合适的问题。
算一下,如果PCIE带宽200GB/S,合计200MB/ms=20MB/100微秒=2MB/10微秒。
每次传输块的大小为:20MB?
–EDIT:
因为讨论较长。此主题题目被我在2012年11月16日 20时12分进行修改为”关于PCIE延迟和性能“。以便更好的彰显讨论。
system
2
当然,从程序设计粒度上看,这个块越小越好,方便。
但从GPU效率上看,越大越好;从GPU资源占用上看,越小越好。
比较合适的是多少?
system
3
1:关于PCI-E的延迟,这个和具体硬件配置有关,我没有具体的数据,请其他人解答。同时,当前intel主流CPU集成了pci-e控制器,显卡的pci-e总线是直通CPU,延迟短一些。以前的系统里面,pci-e控制器在北桥芯片里面,然后北桥再通过系统总线和CPU通信,那样延迟更高。同时复制数据的延迟可能还包括API函数完成一些准备工作所消耗的时间。不过您可以在您的系统上跑一跑profiler,看看传输数据的延迟和用时。
2:kernel的数据传输,如果您的数据是被kernel反复用到的,建议尽量放在显存里,一次性用cudaMemcpy复制过去即可。如果数据copy的时间对您来说也需要掩盖,那么可以使用流来用计算掩盖copy的时间。
3:传输时间和延迟时间是相加的关系,而每复制一次,都有一次延迟时间是跑不掉的,因此传输相同的数据量,传输次数越少,被延迟开销消耗的时间越少,一般来说比较有利。
4:pci-e总线的带宽远远没有那么大,200GB/S已经超过绝大部分GPU的显存带宽了。即使是16X 的pci-e总线,如果是2.0速率的,也就是双向,每向8GB/S的理论速度,实际还达不到,某来源的说法是最大6GB/S以内。如果是3.0速率的,快一倍,达到16GB/S的传输速度。
5:关于2#的说法,“从程序设计粒度上看,(要传输的数据)块越小越好,方便”。无法理解为何这样判断,如果需要用的时候,很零散地从host复制过来,由于pci-e总线的速度和延迟,这往往会导致GPU空闲,使得效能大幅度下降。并且这个真的越小越方便么?表示不理解。
6:关于2#的说法“但从GPU效率上看,越大越好”,这个基本上是正确的,建议将数据尽可能放在GPU的显存端,以提高效能。(这样可以让GPU尽可能快速地获取数据,保证GPU持续的计算而不是等待。同时减少了数据复制次数,减少了一些开销。)
7:关于2#的说法“从GPU资源占用上看,越小越好”无法理解此结论。如果比如说需要的存储空间并没有超过GPU所拥有显存的数量,那么留在那里,不用白不用。如果所需要的存储空间大于一个GPU所拥有的显存数量,那么一般要人为进行拆分和算法改进,将数据放进多块GPU的显存里面,尽量一次放进去别拿出来。如果此时只有一块GPU,需要一边copy和host交换数据,一边计算,那么一般来说会卡在有限的pci-e速度上,导致GPU空闲,性能大幅度下降。
所以楼主在2#最后问到,比较合适的是多少。一般来说就是尽可能用显存,尽可能都放到显存里,都让GPU搞定,别在host端来回倒腾。
欢迎访问论坛,祝您编码愉快~
system
4
不好意思,我给弄错了,例子里的200应该是8。
问这个主要是考虑一般传输多少算效率上可以了?
当然越大越好,但显存空间有限,而且计算需要大量局部存储器空间也很大。
当然我会尽可能的将这个块弄到最大,在显存允许的范围内。
我想一次传输8MB的量可能效率上差不多了吧,1毫秒。
显存确实是不用白不用,尽可能的用满。:lol
system
5
1:“而且计算需要大量局部存储器空间也很大”不明白此句,不做评论。
2:“我想一次传输8MB的量可能效率上差不多了吧,1毫秒。”如果这样对应,那只计算了8MB数据的传输时间,而没有计算API延迟等各种开销。建议以大块数据copy为好。但需要您自行根据实际情况决定。
祝您愉快~
system
6
楼主何必在乎延迟。请考虑吞吐量吧。你的思路需要转变。
楼主反复纠结这里,发的帖子我都从各个方面叙述多次了,实在无法继续。
建议楼主不是写代码"连global memory都不敢用,因为怕延迟”,
怕么啊!!
有if语句存在,就是让你用的!
有global memory存在,就是给你用的!
有cudaMemcpy, 就是给你用的!
有zero copy, 就是给你用的!
用吧!
只要使用,你就会不朽的。
system
7
之所以总是问这些,是因为这些有疑问。
吞吐率我自然会考虑。
自己一想就明白的东西也就没必要问了。总体上的延迟,带宽都需要把握。
可能是因为我过分注重细节了。
我比较追求完美,最高性能是我的追求,而不是程序仅仅能够在GPU上运行。
很感谢您的耐心回复!
system
8
当然,以前CPU编程,很多东西都不知道,也就那么凑合着用了。
GPU是新东西,用它的目的是追求性能,高速度。
所以总是想如何能够最大化加速比。其实很多东西不知道反倒省心,就像CPU里面的东西。呵呵。
system
9
建议以实际运行的profiler结果,不断修正认识和实现,向完美迈进!
(以及6#是在说你考虑的那些实际都不真正影响GPU效率我会随便告诉你么?)
system
11
版主大人对延迟的不屑态度,我很难理解!可能是我对GPU认识不够,恳请指点。
不好意思,我这里只是根据我个人的理解,关于延迟提出我个人的看法。
假设内核的访存与计算密度比例为4:32,就是每访问一个字32条指令的间隔。
这样,计算和带宽刚好匹配。但此时延迟成为瓶颈,因为隐藏延迟需要200条指令。
为了弥补这个延迟,需要程序做出专门的优化,比如提前200条指令访存。
这样,利用多余的寄存器隐藏了延迟。
那么,这个程序可以说针对这个延迟时间做了专门的优化。
但是,对于零拷贝输入,这个优化的程序就会再次出现延迟瓶颈。因为此时延迟数据不同了,优化策略就会不一样了。
因此,我说,零拷贝很多情况下是下策,效率低下不可避免。当然,不能排除实际情况很好的例子。
不知道我的如上理解是否合理,请赐教!
system
12
抱歉,我什么都不懂。建议咨询ICE,PengWang, tianyuan.
system
13
无言。
看来版主大人认为我的解释荒唐了?
认识上的错误请指正。我想谁都会有犯错误的时候。
但您那种对延迟不屑一顾的态度我不能苟同!至少应该解释清楚,让我明白明白吧。
延迟是效率上的一大瓶颈,这个我想你不是不知道。即便我犯了错误,也是明白的指出更好吧。
system
14
横扫版主大人很萌的,你不要黑他。他很重视延迟的,也仔细估算和验证过多少周期延迟可以被掩盖。
关于11#我说两点
1:GPU运行的时候一般会使用数量非常巨大的线程,一个warp的线程的长延迟访存,会被其他warp的计算所掩盖(当然也可以被自己的计算所掩盖,适当将访存提前即可,可能会付出寄存器用量的代价,这里倒是和CPU有点像)。这一点和CPU上不同,CPU上需要自己优化自己在很多周期以前访存,以期需要的时候恰好赶上。所以在GPU上,如果有较多的并发线程,一般的延迟都能得到掩盖。
2:关于文中的零拷贝,我理解为“zero copy”技术。这个一般来说只适合用一次的数据,避免自己copy折腾,让传输过程在后台自己完成。如果需要频繁多次访问,还是建议直接copy到显存上用。zero copy的延迟当然也可以被其他线程的计算掩盖,但是zero copy要通过pci-e总线,延迟要比显存的global memory大得多,带宽要小得多,不容易被掩盖,容易降低计算效能。
以及zero copy本版之前不久有讨论过,可供LZ参考。
system
15
楼主您好!
(1)首先说,我没有表示“我对延迟不屑一顾”
(2)其次,我表示过我的知识层次不够。不能理解您的主题。
(3)再次,因为(2),所以我没有作出你是错误的言论。
首先我建议您仔细阅读我和您的多个主题的多个帖子。
其次我再次建议您和ice, pengwang, tianyuan等人联系,讨论。
ice是资深cuda开发者,
pengwang和tianyuan是NV官方支持。
希望您能理解我,并参考我的建议。
欢迎您继续跟帖留言。
system
16
再次声明,只是就事论就事。
对您对我的很多帮助我一直都是表示十分的感谢的!
曾经解答我的不少问题,很是感激。
如果您觉得有些问题没有必要问,也请直说,我知道了就好。
有些是出于好奇,知道多点总没有坏处吧。
:handshake
system
17
善哉。我丝毫没有生气。只是不懂。而您却强制要求我懂,并要求我解释。。。有点为难了。。呜呜。能力有限的。。。请原谅我。第三次建议考虑ICE, WangPeng, TianYuan.
system
18
请仔细阅读我所写。
关于延迟可以被其他WARP隐藏这一点我知道。只是其他WARP加起来总和也根本无法隐藏的情况。
如果访存较多,这种情况很常见,延迟成为瓶颈是一种没优化程序的常态。
我所叙述的结论就是说即便只读一次,“zero copy”也是低效,因为延迟成为瓶颈。
如果提前copy,延迟就只有一次,而不是内核计算时的很多次。
system
19
既然如此。您可以依然使用您的预读或者说ILP的技巧。没人反对您如此。
因为我看到您反复阐述这点,可能是需要得到肯定,那么我再次肯定的说,您这么做完全没错,同时也是很不错的方式(真心的)。
system
20
至于您楼主位的帖子,在我的实践中,我没有考虑过这么多,甚至都没有去考虑这些。
我喜欢于多开几个stream, 每个stream里面,复制,执行,复制。
这样多个stream交错。可以尽量的让计算和传输来同时进行。
如果能同时传输能力100%使用,计算能力100%使用,我就不去关心具体的某个系统下某PCI-E插槽到cpu的root complex需要经过几个pci-e交换机,他们的拓扑结构如何,云云的。因为此时,我知道我的卡已经在100%的使用它的传输能力和计算能力了,我看到它的SM, 它的copy engine,都在拼命忙碌,我真心为它感到骄傲。同时悄悄的打消了考虑延迟具体是多少,中途中转几次的问题了。
实际上,我没有足够的能力,让我的程序在一个机器上得到它需要的延迟数据,以便能合适的安排线程数,合适的安排预读距离,来规避延迟。但是您看我的卡,它都100%辛苦了。何苦为难它呢。
楼主这是我的习惯。如果您需要更深入的讨论,建议您咨询ice, pengwang, tianyuan.
祝您编码愉快。