tile_static动态索引数组;我应该打扰吗?

时间:2013-11-07 06:07:18

标签: c++ c++-amp

我竭尽全力尝试将经常访问的数据存储在tile_static内存中,以利用随之而来的无限性能必杀技。

但是,我刚刚读到只有某些硬件/驱动程序可以实际动态索引tile_static数组,并且操作可能只会溢出到全局内存。

在一个理想的世界里,我只是去做和描述,但这是一个重大的操作,我想知道我是否在浪费我的时间在这里:

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 /驱动程序是否支持静态数组的动态索引?

1 个答案:

答案 0 :(得分:2)

本地内存的动态索引

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

int staticArray[128]; // not tile_static

这不能动态索引,因为int staticArray[128]数组实际上存储为128个寄存器,而这些寄存器无法动态访问。像这样分配大型数组无论如何都是有问题的,因为它耗尽了大量的寄存器,这些寄存器是GPU上的有限资源。每个线程使用太多寄存器,您的应用程序将无法使用所有可用的并行性,因为某些可用线程将停止等待寄存器变为可用。

在C ++ AMP的情况下,我甚至不确定DX11提供的抽象级别可能会使这有点无关紧要。我不熟悉DX11的专家。

这里有一个很好的解释,In a CUDA kernel, how do I store an array in "local thread memory"?

银行冲突

  

Tile静态内存分为多个模块,简称为   银行。平铺静态存储器通常由16,32或64个存储体组成,   每个都是32位宽。这是特定于特定GPU的   硬件并可能在未来发生变化。平铺静态内存   横跨这些银行。这意味着对于带有磁贴的GPU   如果arr是一个数组,那么用32个存储体实现的静态存储器< float,1>,然后arr [1]和arr [33]在同一个bank中,因为每个float占用一个32位的bank位置。这是关键点   了解何时处理银行冲突。

     

每家银行都可以   每个周期服务一个地址。为获得最佳性能,经线中的线程   应该访问不同库中的数据或者都读取相同的数据   在单个库中,通常由硬件优化的模式。什么时候   遵循这些访问模式,您的应用程序可以最大化   可用磁贴静态内存带宽。在最坏的情况下,多个   同一个warp中的线程访问来自同一个bank的数据。这导致   这些访问要序列化,这可能导致a   性能显着下降。

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

您可以在此处详细了解银行冲突What is a bank conflict? (Doing Cuda/OpenCL programming)