windows C++ 并行编程-C++ AMP 图形(二)

2024-09-01 11:52

本文主要是介绍windows C++ 并行编程-C++ AMP 图形(二),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文中的"显存"还没有找到合适的中文翻译,它的英文名称是texture, 在应用开发者来看,texture是一个名词,在物理上指的是 GPU显存中一段连续的空间。

读取显存对象

可以使用 texture::operator[]、texture::operator() 运算符或 texture::get 方法从 texture 对象中读取。 两个运算符将返回一个值,而不是引用。 因此,你不能使用 texture 写入 texture::operator\[\] 对象。

void readTexture() {std::vector<int_2> src;for (int i = 0; i <16 *32; i++) {int_2 i2(i, i);src.push_back(i2);}std::vector<int_2> dst(16* 32);array_view<int_2, 2> arr(16, 32, dst);arr.discard_data();const texture<int_2, 2> tex9(16, 32, src.begin(), src.end());parallel_for_each(tex9.extent, [=, &tex9] (index<2> idx) restrict(amp) { // Use the subscript operator.arr[idx].x += tex9[idx].x; // Use the function () operator.arr[idx].x += tex9(idx).x; // Use the get method.arr[idx].y += tex9.get(idx).y; // Use the function () operator.arr[idx].y += tex9(idx[0], idx[1]).y;});arr.synchronize();
}

 下面的代码示例演示如何在短矢量中存储显存通道,然后访问作为短矢量属性的各个标量元素。

void UseBitsPerScalarElement() { // Create the image data. // Each unsigned int (32-bit) represents four 8-bit scalar elements(r,g,b,a values).const int image_height = 16;const int image_width = 16;std::vector<unsigned int> image(image_height* image_width);extent<2> image_extent(image_height, image_width);// By using uint_4 and 8 bits per channel, each 8-bit channel in the data source is // stored in one 32-bit component of a uint_4.texture<uint_4, 2> image_texture(image_extent, image.data(), image_extent.size()* 4U,  8U);// Use can access the RGBA values of the source data by using swizzling expressions of the uint_4.parallel_for_each(image_extent,[&image_texture](index<2> idx) restrict(amp){ // 4 bytes are automatically extracted when reading.uint_4 color = image_texture[idx];unsigned int r = color.r;unsigned int g = color.g;unsigned int b = color.b;unsigned int a = color.a;});
}

 下表列出了每种短矢量类型的每通道有效位数。

 写入显存对象

使用 texture::set 方法可写入 texture 对象。 显存对象可以是只读或读/写属性。 显存对象若要可读写,必须满足以下条件:

T 只有一个标量组件。 (不允许使用短矢量。)

T 不是 double、norm 或 unorm。

texture::bits_per_scalar_element 属性为 32。

如果不符合这三个条件,则 texture 对象为只读对象。 编译期间将检查前两个条件。 如果有代码尝试写入 readonly 显存对象,将产生编译错误。 texture::bits_per_scalar_element 条件在运行时进行检查,如果尝试写入只读的 texture 对象,则运行时将产生 unsupported_feature 异常。

下面的代码示例向一个显存对象写入了多个值。

void writeTexture() {texture<int, 1> tex1(16);parallel_for_each(tex1.extent, [&tex1] (index<1> idx) restrict(amp) {tex1.set(idx, 0);});
}
 复制显存对象

如下面的代码示例所示,可以使用 copy 函数或 copy_async 函数在显存对象之间进行复制。

void copyHostArrayToTexture() { // Copy from source array to texture object by using the copy function.float floatSource[1024* 2];for (int i = 0; i <1024* 2; i++) {floatSource[i] = (float)i;}texture<float_2, 1> floatTexture(1024);copy(floatSource, (unsigned int)sizeof(floatSource), floatTexture);// Copy from source array to texture object by using the copy function.char charSource[16* 16];for (int i = 0; i <16* 16; i++) {charSource[i] = (char)i;}texture<int, 2> charTexture(16, 16, 8U);copy(charSource, (unsigned int)sizeof(charSource), charTexture);// Copy from texture object to source array by using the copy function.copy(charTexture, charSource, (unsigned int)sizeof(charSource));
}

你还可以使用 texture::copy_to 方法从一个纹理复制到另一个纹理。 这两个纹理可以位于不同的 accelerator_view 上。 当复制到 writeonly_texture_view 对象时,数据将复制到基础 texture 对象。 源和目标 texture 对象上的每标量元素位数和范围必须相同。 如果不符合这些需求,运行时将引发异常。

显存视图类

C++ AMP 介绍了 Visual Studio 2013 中的 texture_view 类。 显存视图支持与 texture 类相同的纹素类型和秩,但是与显存不同,它们允许访问其他硬件功能,如显存采样和 mipmap。 显存视图支持对基础显存数据进行只读、只写和读/写访问。

  • 只读访问由 texture_view<const T, N> 模板专用化提供,支持具有 1 个、2 个或 4 个组件的元素、显存采样以及动态访问在实例化视图时确定的一系列 mipmap 级别;
  • 写入访问由非专用模板类 texture_view<T, N> 提供,支持具有 2 个或 4 个组件的元素,并且可以访问在实例化视图时确定的一个 mipmap 级别。 它不支持采样;
  • 读写访问由非专用模板类 texture_view<T, N> 提供,与显存一样,支持仅具有 1 个组件的元素;视图可以访问在实例化视图时确定的一个 mipmap 级别。 它不支持采样;

显存视图类似于数组视图,但是不提供 array_view 类通过 array 类提供的自动数据管理和移动功能。 texture_view 只能在基础显存数据所在的快捷键视图中进行访问。

这篇关于windows C++ 并行编程-C++ AMP 图形(二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1126863

相关文章

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

C++11右值引用与Lambda表达式的使用

《C++11右值引用与Lambda表达式的使用》C++11引入右值引用,实现移动语义提升性能,支持资源转移与完美转发;同时引入Lambda表达式,简化匿名函数定义,通过捕获列表和参数列表灵活处理变量... 目录C++11新特性右值引用和移动语义左值 / 右值常见的左值和右值移动语义移动构造函数移动复制运算符

C++中detach的作用、使用场景及注意事项

《C++中detach的作用、使用场景及注意事项》关于C++中的detach,它主要涉及多线程编程中的线程管理,理解detach的作用、使用场景以及注意事项,对于写出高效、安全的多线程程序至关重要,下... 目录一、什么是join()?它的作用是什么?类比一下:二、join()的作用总结三、join()怎么

Windows环境下解决Matplotlib中文字体显示问题的详细教程

《Windows环境下解决Matplotlib中文字体显示问题的详细教程》本文详细介绍了在Windows下解决Matplotlib中文显示问题的方法,包括安装字体、更新缓存、配置文件设置及编码調整,并... 目录引言问题分析解决方案详解1. 检查系统已安装字体2. 手动添加中文字体(以SimHei为例)步骤

Ubuntu 24.04启用root图形登录的操作流程

《Ubuntu24.04启用root图形登录的操作流程》Ubuntu默认禁用root账户的图形与SSH登录,这是为了安全,但在某些场景你可能需要直接用root登录GNOME桌面,本文以Ubuntu2... 目录一、前言二、准备工作三、设置 root 密码四、启用图形界面 root 登录1. 修改 GDM 配

C++中全局变量和局部变量的区别

《C++中全局变量和局部变量的区别》本文主要介绍了C++中全局变量和局部变量的区别,全局变量和局部变量在作用域和生命周期上有显著的区别,下面就来介绍一下,感兴趣的可以了解一下... 目录一、全局变量定义生命周期存储位置代码示例输出二、局部变量定义生命周期存储位置代码示例输出三、全局变量和局部变量的区别作用域

C++中assign函数的使用

《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)

c++ 类成员变量默认初始值的实现

《c++类成员变量默认初始值的实现》本文主要介绍了c++类成员变量默认初始值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录C++类成员变量初始化c++类的变量的初始化在C++中,如果使用类成员变量时未给定其初始值,那么它将被

C++中NULL与nullptr的区别小结

《C++中NULL与nullptr的区别小结》本文介绍了C++编程中NULL与nullptr的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编... 目录C++98空值——NULLC++11空值——nullptr区别对比示例 C++98空值——NUL

C++ Log4cpp跨平台日志库的使用小结

《C++Log4cpp跨平台日志库的使用小结》Log4cpp是c++类库,本文详细介绍了C++日志库log4cpp的使用方法,及设置日志输出格式和优先级,具有一定的参考价值,感兴趣的可以了解一下... 目录一、介绍1. log4cpp的日志方式2.设置日志输出的格式3. 设置日志的输出优先级二、Window