C++ tile_静态动态索引数组;我应该麻烦吗?

C++ tile_静态动态索引数组;我应该麻烦吗?,c++,c++-amp,C++,C++ Amp,我将不遗余力地尝试在tile\u static内存中存储频繁访问的数据,以利用随之而来的无限性能涅盘 然而,我刚刚读到,实际上只有某些硬件/驱动程序可以动态索引tile_静态数组,而且操作可能会溢出到全局内存中 在一个理想的世界里,我只想做这件事,并对其进行分析,但这是一项重大的行动,我想知道我是否在这里浪费时间: tile_static int staticArray[128]; int resultFast = staticArray[0]; // this is super fast /

我将不遗余力地尝试在
tile\u static
内存中存储频繁访问的数据,以利用随之而来的无限性能涅盘

然而,我刚刚读到,实际上只有某些硬件/驱动程序可以动态索引tile_静态数组,而且操作可能会溢出到全局内存中

在一个理想的世界里,我只想做这件事,并对其进行分析,但这是一项重大的行动,我想知道我是否在这里浪费时间:

tile_static int staticArray[128];
int resultFast = staticArray[0]; // this is super fast

// but what about this:   
i = // dynamically derived value!
int resultNotSoFast = staticArray[i]; // is this faster than getting it from global memory?

如何确定我的GPU/驱动程序是否支持静态数组的动态索引?

本地内存的动态索引

所以我在这方面做了一些挖掘,因为我也想了解这一点。 如果您指的是本地内存的动态索引,而不是
tile\u static
(或者用CUDA的说法,“共享内存”)。在上面的示例中,
staticArray
应声明为:

int staticArray[128]; // not tile_static
这无法动态索引,因为
int staticArray[128]
的数组实际上存储为128个寄存器,并且无法动态访问这些寄存器。像这样分配大型阵列无论如何都是有问题的,因为它会占用大量寄存器,而这些寄存器在GPU上是有限的资源。每个线程使用过多的寄存器,应用程序将无法使用所有可用的并行性,因为一些可用线程将暂停,等待寄存器变为可用

在C++的情况下,我甚至不确定DX11提供的抽象级别会使这一点变得不相关。我对DX11还不够了解

这里有一个很好的解释

银行冲突

平铺静态内存分为多个模块,称为 银行。平铺静态内存通常由16、32或64个存储组组成, 每个都是32位宽。这是特定于特定GPU的 未来可能会发生变化。平铺静态内存是 交错在这些河岸上。这意味着对于具有平铺的GPU 使用32个存储组实现的静态内存如果arr是一个数组,则arr[1]和arr[33]位于同一个存储组中,因为每个浮点占用一个32位存储组位置。这是解决问题的关键 了解如何处理银行冲突

每家银行都可以 每个周期服务一个地址。为获得最佳性能,请在扭曲中使用螺纹 应该访问不同银行的数据,还是读取相同的数据 在单个银行中,通常由硬件优化的模式。什么时候 遵循这些访问模式,您的应用程序可以最大限度地提高 可用平铺静态内存带宽。在最坏的情况下,多个 同一扭曲中的线程访问同一银行的数据。这导致 这些访问将被序列化,这可能导致 性能显著下降

我认为混淆的关键点可能是(基于您的一些其他问题)内存库是32位宽的,但负责访问内存库中的所有内存,这些内存将是静态内存总量的1/16、1/32或1/64


您可以在此处阅读有关银行冲突的更多信息

您在哪里读到的。它将帮助我回答这个问题。@AdeMiller我在这里读到它:特别是关于共享内存:
一个扭曲中有32个线程,而共享内存库正好有32个。由于每个银行每个周期只提供一个请求,因此对同一银行的多个同时访问将导致所谓的银行冲突。这将在下一篇文章中进一步讨论。
@AdeMiller抱歉,我可能把事情搞糊涂了。老实说,这些新术语让我很困惑。我想你是对的,我说的是本地内存,而那篇关于共享内存的文章则有所不同。这很难。在GPU编程中,有效的权衡是,您需要考虑并实现不同级别的缓存在CPU上为您提供的许多功能。作为回报,您可以获得更好的性能。我给你的答案增加了另一部分。