设为首页 加入收藏

TOP

C++ AMP 介绍(二)(一)
2015-07-20 17:31:09 来源: 作者: 【 】 浏览:6
Tags:AMP 介绍

C++ AMP 介绍(二)

最后更新日期:2014-05-02

阅读前提:《C++ AMP介绍(一)》

环境:Windows 8.1 64bit英文版,Visual Studio 2013 Update1英文版,Nvidia QuadroK600 显卡

内容简介

介绍C++ AMP的 array、array_view、extent类和平铺的知识。

正文

数据的移动

array和 array_view两个数据容器(模板类)用于把数据从运行时库(CPU)移到加速器(显卡或通用计算卡)上,array类在构造时建立数据的深拷贝,把数据复制到加速器(GPU)上,而array_view类是个包装类,仅仅当核心函数(kernel function)要用到数据时,才把源数据复制到加速器上。

#include 
  
   
using namespace concurrency;

//演示array类的使用方式
void test_array()
{
	//测试数据
	std::vector
   
     data(5); for (int count = 0; count < 5; count++) { data[count] = count; } //构造array实例 array
    
      a(5, data.begin(), data.end()); parallel_for_each( a.extent, [=, &a](index<1> idx) restrict(amp) { a[idx] = a[idx] * 10; } ); //array实例a不需要调用同步方法 //但是需要赋值给data data = a; //输出0,10,20,30,40 for (int i = 0; i < 5; i++) { std::cout << data[i] << "\n"; } }
    
   
  


array_view同array之间几乎有相同的成员,但是它们底层的行为不一样,所以当你建立两个指向同一个数据源的array_view实例时,实际上它们指向同一个内存地址,数据只有当需要的时候才会被复制到加速器中,所以你得注意数据的同步,array_view类的主要好处是数据仅当要被加速器用到的时候才会被移动。

共享内存是能被CPU和GPU访问的内存,array类可以控制共享内存的存取方式,但是首先我们需要测试加速器是不是支持共享内存,下面是array使用共享内存的示例代码。

int test_sharedMemory()
{
	// 一台计算机中可能有多块加速器,取默认加速器
	accelerator acc = accelerator(accelerator::default_accelerator);

	// 测试默认加速器是否支持共享内存
	if (!acc.supports_cpu_shared_memory)
	{
		std::cout << "The default accelerator does not support shared memory" << std::endl;
		return 1;
	}

	// 设置cpu默认存取方式
	acc.set_default_cpu_access_type(access_type_read_write);

	//为acc加速器建立accelerator_view(加速器视图)实例
	//读写方式默认为加速器default_cpu_access_type属性的设定
	accelerator_view acc_v = acc.default_view;

	// extent指示array实例建立一个含10个元素的一维数组
	extent<1> ex(10);

	// 指定加速器视图,输入数组在CPU上只写
	array
  
    arr_w(ex, acc_v, access_type_write);

	// 指定加速器视图,输出数组在CPU上只读
	array
   
     arr_r(ex, acc_v, access_type_read); // 指定加速器视图,可以在CPU上读写的数组 array
    
      arr_rw(ex, acc_v, access_type_read_write); return 0; }
    
   
  


index 类

index类指定元素在array或array_view对象中的位置,下面是index类的使用示例代码

void test_indexClass()
{
	int aCPP[] = { 1, 2, 3,
		4, 5, 6 };
	//新建2维(两行三列)array_view包装器
	array_view
  
    a(2, 3, aCPP);
	index<2> idx(1, 2);

	//输出6
	std::cout << a[idx] << "\n";
}
  


extent类

虽然extent类在很多场合下不是必要的,但是微软的部分示例代码使用到了extent class,所以有必要介绍下extent class。

extentclass用来指定array或array_view各个维度的元素数量,你可以使用extent class建立array或array_view对象,也可以从array或array_view对象中存取extent,下面的例子演示了extent class的使用。

void test_extentClass()
{
	int aCPP[] = { 111, 112, 113, 114, 
		           121, 122, 123, 124, 
				   131, 132, 133, 134,

				   211, 212, 213, 214,
				   221, 222, 223, 224,
				   231, 232, 233, 234 };
	extent<3> e(2, 3, 4);
	array_view
  
    a(e, aCPP);

	//断言extent[0],[1],[2]的属性分别为2、3、4
	assert(2 == a.extent[0]);	
	assert(3 == a.extent[1]);
	assert(4 == a.extent[2]);	
}
  


parallel_for_each函数

我们在上篇文章中调用过parallel_for_each函数,它有两个入口参数,第一个入口参数为计算域,是个extent或tiled_extent对象,定义了要在加速器上并发运行的线程集合,它会为每个元素生成一根用于计算的线程。第二个参数是lambda表达式,定义了要在每根线程上运行的代码。

加速代码: 砖面(Tiles )和边界(Barriers)

将全体线程划分为若干个具有相等数量矩形(M*N根)线程集合,每个集合称为tile(砖面),多个tile(砖面)组成全体线程,叫做平铺(tiling)。

若要使用平铺,在parallel_for_each 方法中的计算域上调用 extent::tile 方法,并在 lambda 表达式中使用 tiled_index 对象。

下面是两张来自微软官网的砖面(tile)的组织图,可以看到如何索引元素。

图中的idx是index类,sample是全局空间(array或array_view对象)

\

下图中的t_idx是index类,descriptions是全局空间(array或array_view对象)


\

下面这个来自微软官方的例子,每2*2=4根线程组成一个砖面(tile),计算砖面(tile)中元素的平均值。

void test_tile()
{
	// 测试样本:
	int sampledata[] = {
		2, 2, 9, 7, 1, 4,
		4, 4, 8, 8, 3, 4,
		1, 5, 1, 2, 5, 2,
		6, 8, 3, 2, 7, 2 };

	// The tiles(下面是6个砖面):
	// 2 2    9 7    1 4
	// 4 4    8 8    3 4
	//
	// 1 5    1 2    5 2
	// 6 8    3 2    7 2

	// averagedata用来存放运算结果:
	int averagedata[] = {
		0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0,
	};

	//每四个元素(四根线程)组成一个tile(砖面),所以共有六个tile(砖面)
	array_view
  
    sample(4, 6, sampledata);
	array_view
   
     average(4, 6, averagedata); //通过[1]extent.tile代替extent[2
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇poj1655 Balancing Act 求树的重心 下一篇Leetcode:signal_number_ii

评论

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

·在 Redis 中如何查看 (2025-12-26 03:19:03)
·Redis在实际应用中, (2025-12-26 03:19:01)
·Redis配置中`require (2025-12-26 03:18:58)
·Asus Armoury Crate (2025-12-26 02:52:33)
·WindowsFX (LinuxFX) (2025-12-26 02:52:30)