设为首页 加入收藏

TOP

C++ AMP 介绍(二)(二)
2015-07-20 17:31:09 来源: 作者: 【 】 浏览:8
Tags:AMP 介绍
]tiled_index代替index,启用平铺模式 parallel_for_each( // 把extent切分为以2*2为单位的tile(砖面) sample.extent.tile<2, 2>(), [=](tiled_index<2, 2> idx) restrict(amp) { //tile_static关键字的变量范围是整个tile(砖面) //所以每个tile(砖面)(2*2=4根线程)只实例化一个tile_static tile_static int nums[2][2]; //tile(砖面)中的所有线程分别运行下面的代码 //把值复制到tile_static实例nums,所以同一个nums会被赋值2*2=4次 nums[idx.local[1]][idx.local[0]] = sample[idx.global]; //等待tile(砖面)中的所有线程,运行完上面这段代码 idx.barrier.wait(); //现在nums中的2*2=4个元素已经有有效值了 //tile(砖面)中的所有线程再次分别运行下面的代码 //计算平均值, int sum = nums[0][0] + nums[0][1] + nums[1][0] + nums[1][1]; //把计算结果复制到array_view对象中. average[idx.global] = sum / 4; } ); //打印运算结果 for (int i = 0; i < 4; i++) { for (int j = 0; j < 6; j++) { std::cout << average(i, j) << " "; } std::cout << "\n"; } // Output: // 3 3 8 8 3 3 // 3 3 8 8 3 3 // 5 5 2 2 4 4 // 5 5 2 2 4 4 }

使用平铺的好处是,从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


首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇poj1655 Balancing Act 求树的重心 下一篇Leetcode:signal_number_ii

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·每日一道面试题-多线 (2025-12-26 06:20:17)
·java项目中哪些地方 (2025-12-26 06:20:14)
·Java真的是要没落了 (2025-12-26 06:20:12)
·C++ Lambda表达式保 (2025-12-26 05:49:45)
·C++ Lambda表达式的 (2025-12-26 05:49:42)