Mic*_* IV 20 gpu gpgpu gpu-programming vulkan
我曾经偶然发现一个术语"非连贯"和"连贯"的记忆
与图形编程相关的技术论文.我一直在寻找一个简单而明确的解释,但是发现了这种类型的"硬核"论文.我很高兴收到外行人的样式答案,关于GPU体系结构实际上是什么连贯的内存以及它是如何实现的与其他(可能不相干)的内存类型进行比较.
Nic*_*las 26
记忆是记忆.但是不同的东西可以访问那个记忆.GPU可以访问内存,CPU可以访问内存,也许是其他硬件位,无论如何.
如果读者可以看到其他人对该内存所做的更改,则特定事物对内存具有"连贯"访问权限.现在,你可能会认为这是愚蠢的.毕竟,如果内存已被更改,有人可能无法看到它?
简单地说,缓存.
事实证明,改变内存是昂贵的.所以我们尽一切可能避免改变记忆,除非我们绝对必须这样做.当您将CPU中的单个字节写入内存中的指针时,CPU尚未写入该字节.或者至少,不是记忆.它将其写入该内存的本地副本,称为"缓存".
这样做的原因是,一般来说,应用程序不会写入(或读取)单个字节.它们更有可能以小块的形式写入(并读取)大量字节.因此,如果您要执行内存加载或存储等昂贵操作,则应加载或存储大量内存.因此,您将所有要进行的更改存储到缓存中的一块内存中,然后在将来的某个时刻将该缓存的块写入实际内存.
但是,如果您有两个使用相同内存的独立设备,则需要某种方法来确保写入一个设备使其他设备可见.大多数GPU无法读取CPU缓存.大多数CPU语言没有语言级支持来说"嘿,我写入内存的那些东西?我真的是要你现在把它写入内存." 所以你通常需要一些东西来确保变化的可见性.
在福尔康,被标记的记忆"HOST_COHERENT"的意思是,如果你写内存(通过映射的指示器,因为这是唯一的福尔康,您可以直接写入到内存的方式),你不会需要使用特殊的功能,使确保GPU可以看到这些变化.GPU保证了任何变化的可见性.如果该标志在内存中不可用,则必须使用Vulkan API来确保要访问的特定数据区域的一致性.
对于连贯的内存,硬件方面正在进行两件事之一.CPU访问内存不会缓存在任何CPU的缓存中,或者GPU可以直接访问CPU的缓存(可能是由于与CPU相同的芯片).你通常可以告诉后者正在发生,因为Vulkan的片上GPU实现并不打算提供非连贯的内存选项.
如果内存是连贯的,则访问该内存的所有线程必须始终就内存状态达成一致,例如:如果线程0读取内存位置A并且线程1同时读取相同位置,则两个线程应始终读取相同内容值.
但是如果内存不连贯,那么线程A和B可能会读回不同的值.线程0可以认为位置A包含1,而线程认为该位置包含2.不同的线程将具有内存的不连贯视图.
使用大量内核很难实现一致性.通常每个核心都必须知道来自所有其他核心的内存访问.因此,如果四核CPU中有4个内核,那么一致性并不难实现,因为每个内核必须了解其他3个内核的内存访问地址,但在具有16个内核的GPU中,必须让每个内核都知道内存访问15个其他核心.核使用所谓的"高速缓存一致性协议"来交换关于其高速缓存的内容的数据.
这就是为什么GPU通常只支持有限形式的一致性.如果某些内存位置是只读的或仅由单个线程访问,则不需要一致性.如果高速缓存很小并且并不总是需要一致性,而只是在程序的特定指令处,则可以在特定存储器访问之前或之后使用高速缓存刷新来实现程序的正确行为.
如果您的硬件同时提供相干和非连贯的内存类型,那么您可以预期非连贯内存将更快,但如果您尝试使用此内存运行并行算法,它们将以非常奇怪的方式失败.
| 归档时间: |
|
| 查看次数: |
3299 次 |
| 最近记录: |