使用平铺的好处是,从tile_static变量存取数据要比从全局空间(array和array_view对象)要快。为了从平铺中得到性能优势,我们的算法必须把计算域拆分为tile(砖面)然后把数据放到tile_static变量中加快数据存取速度。
注意不要使用类似下面的代码来累加tile(砖面)中的数据,
tile_static float total;
total += matrix[t_idx];‘
原因[1]total的初始值是不确定的,所以第二句代码的运算没有意义。
原因[2]由于tile(砖面)中的多根线程竞争同一个title_static变量,计算结果会不确定。
内存屏障(MemoryFences)
在restrict(amp)限定中,有两种内存必须要同步:
全局内存:array或array_view实例
tile_static内存:tile(砖面)内存
内存屏障确保两种内存的线程同步,要调用内存屏障可以使用下面三种方法:
tile_barrier::wait(或tile_barrier::wait_with_all_memory_fence)方法: 建立全局内存和tile_static内存的屏障。
tile_barrier::wait_with_global_memory_fence方法 : 仅建立全局内存的屏障
tile_barrier::wait_with_tile_static_memory_fence 方法 :仅建立tile_static内存的屏障
调用特定类型的屏障(fence)可以提高你应用的性能,在下面的例子中 tile_barrier::wait_with_tile_static_memory_fence 方法的调用代替tile_barrier::wait方法的调用提高了应用的性能。
// 使用tile_static内存屏障 parallel_for_each(matrix.extent.tile(), [=, &averages](tiled_index t_idx) restrict(amp) { // 把数据从全局内存中复制到title_static内存中. tile_static floattileva lues[SAMPLESIZE][SAMPLESIZE]; tileva lues[t_idx.local[0]][t_idx.local[1]] = matrix[t_idx]; // 等待title_static内存中的数据复制完毕 t_idx.barrier.wait_with_tile_static_memory_fence(); // 如果你移除if语句,代码会把被tile(砖面)中的所有线程调用,这样每个 // tile(砖面)中的元素都会被分配一个同样的平均值. if (t_idx.local[0] == 0&& t_idx.local[1] == 0) { for (int trow = 0; trow
restrict(amp)修饰的代码段是在加速器(GPU)上运行的,默认在里面的代码段,下断点不会Break(进入),在[Solution Explorer]窗口中点击项目名称,快捷键[Alt]+[Enter],打开当前项目属性页,[Configuration Properties]->[Debugging]->[Debugger Type]默认为“Auto”,改为“GPU Only”就可以Debug当前项目加速器(GPU)上运行的代码了。
据官网介绍,无符号整数的处理速度要比带符号整数快,所以尽量用无符号整数吧。
参考资料
《Using Tiles》
http://msdn.microsoft.com/en-us/library/vstudio/hh873135.aspx
《使用平铺》
http://msdn.microsoft.com/zh-cn/library/vstudio/hh873135.aspx