我知道CUDA GPU上有多处理器,其中包含CUDA核心.在我的工作场所,我使用的是GTX 590,它包含512个CUDA内核,16个多处理器,其warp大小为32.因此,这意味着每个多处理器中有32个CUDA内核,它们在同一个warp中完全相同的代码.最后,每块大小的最大线程数为1024.
我的问题是块大小和多处理器数量 - warp大小是如何完全相关的.让我告诉我对情况的理解:例如,我在GTX 590上分配了最大threadPerBlock大小为1024的N个块.据我从CUDA编程指南和其他来源的理解,这些块首先由硬件枚举. .在这种情况下,来自N个块的16被分配给不同的多处理器.每个块包含1024个线程,硬件调度程序将32个这些线程分配给单个多处理器中的32个核心.同一多处理器(warp)中的线程处理代码的同一行,并使用当前多进程的共享内存.如果当前的32个线程遇到像存储器读写这样的片外操作,则它们将替换为来自当前块的另一组32个线程.所以,实际上有32个线程,其中在单个块恰好在任何给定时间并行运行在多处理器,而不是整个的1024的最后,如果一个块完全被多处理器中,从一个新的线程块处理N个线程块的列表插入到当前的多处理器中.最后,在执行CUDA内核期间,GPU中总共有512个并行运行的线程.(我知道如果一个块使用的寄存器多于单个多处理器上可用的寄存器,那么它被分成两个多处理器,但我们假设在我们的情况下每个块可以适合单个多处理器.)
那么,我的CUDA并行执行模型是否正确?如果没有,有什么不对或缺失?我想微调我正在处理的当前项目,所以我需要最正确的工作模型.
我如何实现一个FIFO缓冲区,我可以有效地向头部添加任意大小的字节块,从中可以有效地从尾部弹出任意大小的字节块?
背景:
我有一个类,它以类似文件的对象从任意大小的块中读取字节,并且本身就是一个类文件对象,客户端可以从中读取任意大小的块中的字节.
我实现这一点的方法是,每当客户端想要读取一大块字节时,该类将重复读取基础文件类对象(具有适合这些对象的块大小)并将字节添加到FIFO的头部队列,直到队列中有足够的字节为客户端提供所请求大小的块.然后它将这些字节从队列尾部弹出并将它们返回给客户端.
当基础文件类对象的块大小远大于客户端从类中读取时使用的块大小时,会出现性能问题.
假设基础文件类对象的块大小为1 MiB,客户端读取的块大小为1 KiB.客户端第一次请求1 KiB时,该类必须读取1 MiB并将其添加到FIFO队列中.然后,对于该请求和随后的1023个请求,类必须从FIFO队列的尾部弹出1 KiB,其大小从1 MiB逐渐减小到0字节,此时循环再次开始.
我目前用StringIO对象实现了它.将新字节写入StringIO对象的末尾很快,但是从头开始删除字节非常慢,因为必须创建一个新的StringIO对象,它保存整个前一个缓冲区的副本减去第一个字节块.
处理类似问题的问题往往指向deque容器.但是,deque实现为双向链表.将一个块写入双端队列需要将块拆分为对象,每个对象包含一个字节.然后,deque将向每个对象添加两个指针用于存储,与字节相比,可能将存储器需求增加至少一个数量级.此外,遍历链表并处理每个对象都需要很长时间才能将块拆分为对象并将对象连接成块.
在Compute Capability 2.0(Fermi)发布之后,我想知道是否有任何用例共享内存.也就是说,何时使用共享内存比让L1在后台执行魔术更好?
共享内存是否只是为了让CC <2.0设计的算法在没有修改的情况下高效运行?
要通过共享内存进行协作,块中的线程会写入共享内存并与之同步__syncthreads()
.为什么不简单地写入全局内存(通过L1),并与__threadfence_block()
?同步?后一个选项应该更容易实现,因为它不必涉及值的两个不同位置,并且它应该更快,因为没有从全局到共享内存的显式复制.由于数据在L1中缓存,因此线程不必等待数据实际上一直到全局内存.
使用共享内存,可以保证在整个块的持续时间内放置的值保持不变.这与L1中的值相反,如果它们不经常使用,则会被逐出.是否有任何情况下,在共享内存中缓存这些很少使用的数据比让L1根据算法实际具有的使用模式管理它们更好?
在SO上,找到了以下用于绘制实心圆的简单算法:
for(int y=-radius; y<=radius; y++)
for(int x=-radius; x<=radius; x++)
if(x*x+y*y <= radius*radius)
setpixel(origin.x+x, origin.y+y);
Run Code Online (Sandbox Code Playgroud)
绘制填充椭圆是否有同样简单的算法?
当我编辑.cu
在Microsoft Visual Studio 2010中的文件时,编辑器把它当作一个普通的文本文件(有关键字没有颜色,如int
,float
等右括号不突出).
如何.cu
在Visual Studio中启用文件的语法突出显示,以便编辑.cu
文件就像编辑常规C/C++文件一样?
当我声明C++变量时,我这样做:
int a,b,c,d;
Run Code Online (Sandbox Code Playgroud)
要么
string strA,strB,strC,strD;
Run Code Online (Sandbox Code Playgroud)
即,首先是类型,然后是逗号分隔的变量名称列表.
但是,我声明了这样的指针:
int *a,*b,*c,*d;
Run Code Online (Sandbox Code Playgroud)
和这样的引用:
int &a,&b,&c,&d;
Run Code Online (Sandbox Code Playgroud)
应该是一致的
int* a,b,c,d;
Run Code Online (Sandbox Code Playgroud)
和
int& a,b,c,d;
Run Code Online (Sandbox Code Playgroud)
为什么不一致?
有时,我的CUDA程序中的错误会导致桌面图形中断(在Windows中).通常,屏幕保持稍微可读,但是当图形改变时,例如当拖动窗口时,出现许多半随机彩色像素和小块.
我试图通过更改桌面分辨率来重置GPU和驱动程序,但这没有用.我发现的唯一解决方法是重启计算机.
是否有一个程序或我可以使用一些技巧来重置驱动程序和GPU重置?
背景:
我有1.0,1.1,1.3和2.0卡,但我现在只有1.1和2.0卡.我在1.0和1.1上看过这个问题.我很确定我在1.3上看过它.我不确定2.0.内存保护是否在1.3左右增加了一些时间?我几乎可以肯定这不是由于硬件不稳定,因为问题似乎是由我的代码中的错误引发的,并且在修复错误时消失了.运行完成的代码后,卡已稳定.我在1.1卡上看到这个问题之后写了这个问题,但是在我修复了一个bug之后它就消失了,现在我没有任何代码可以重现它.也许我应该尝试写入1.1卡上的随机位置,看看是否有任何事情......
CUDA提供内置的矢量数据类型uint2
,uint4
等等.使用这些数据类型有什么好处吗?
让我们假设我有一个由两个值A和B组成的元组.将它们存储在内存中的一种方法是分配两个数组.第一个数组存储所有A值,第二个数组存储与A值对应的索引处的所有B值.另一种方法是分配一个类型的数组uint2
.我应该使用哪一个?推荐哪种方式?难道成员uint3
即x
,y
,z
在内存中驻留侧方?
我有一个CUDA内核,可以调用一系列设备函数.
获取每个设备功能的最佳方法是什么?
在其中一个设备功能中获取代码段执行时间的最佳方法是什么?