DAY20:阅读Surface Memory

3.2.11.2. Surface Memory

For devices of compute capability 2.0 and higher, a CUDA array (described in Cubemap Surfaces), created with the cudaArraySurfaceLoadStore flag, can be read and written via a surface object or surface reference using the functions described in Surface Functions.

Table 14 lists the maximum surface width, height, and depth depending on the compute capability of the device.

(二维码扫描可以看到Table 14的图)

3.2.11.2.1. Surface Object API

A surface object is created using cudaCreateSurfaceObject() from a resource description of type struct cudaResourceDesc.

The following code sample applies some simple transformation kernel to a texture.

3.2.11.2.2. Surface Reference API

A surface reference is declared at file scope as a variable of type surface:

surface<void, Type> surfRef;

where Type specifies the type of the surface reference and is equal to cudaSurfaceType1D, cudaSurfaceType2D, cudaSurfaceType3D, cudaSurfaceTypeCubemap,cudaSurfaceType1DLayered, cudaSurfaceType2DLayered, or cudaSurfaceTypeCubemapLayered; Type is an optional argument which defaults to cudaSurfaceType1D. A surface reference can only be declared as a static global variable and cannot be passed as an argument to a function.

Before a kernel can use a surface reference to access a CUDA array, the surface reference must be bound to the CUDA array using cudaBindSurfaceToArray().

The following code samples bind a surface reference to a CUDA array cuArray:

· Using the low-level API:

· Using the high-level API:

A CUDA array must be read and written using surface functions of matching dimensionality and type and via a surface reference of matching dimensionality; otherwise, the results of reading and writing the CUDA array are undefined.

Unlike texture memory, surface memory uses byte addressing. This means that the x-coordinate used to access a texture element via texture functions needs to be multiplied by the byte size of the element to access the same element via a surface function. For example, the element at texture coordinate x of a one-dimensional floating-point CUDA array bound to a texture reference texRef and a surface reference surfRef is read using tex1d(texRef, x) via texRef, but surf1Dread(surfRef, 4*x) via surfRef. Similarly, the element at texture coordinate x and y of a two-dimensional floating-point CUDA array bound to a texture reference texRef and a surface reference surfRef is accessed using tex2d(texRef, x, y) via texRef, but surf2Dread(surfRef, 4*x, y) via surfRef (the byte offset of the y-coordinate is internally calculated from the underlying line pitch of the CUDA array).

The following code sample applies some simple transformation kernel to a texture.

本文备注/经验分享:

Surface Memory——

如同之前我们说过的, surface等于非常简化版本的texture,texture具有的特殊功能它都没有。例如texture的坐标变换,插值,高级边界处理之类的。还有图形学用的mipmap,lod啥的,但Surface同样可以绑定CUDA Array,同时可以写入。而普通指针读写只能应付普通的线性内存(显存)。以及,surface只有简单的边界处理,例如越界返回0(读取)或者越界写入忽略之类的。你应当将它当成一个极度简化版本的texture,或者当成只有存储读写功能,但没有采样器(sampler,也就是之前你看到的那些texture的高级特性)的简化版本texture。能写入这个非常重要——在以前没有写入功能的时候,更新CUDA Array非常麻烦,现在只需要在kernel上启动一个surface更新写入即可。这个是个很好的功能,否则以前需要从host端折腾,现在可以直接从device上启动kernel处理了。其他的都一样。

Surface Object API——

在这段演示的代码里面, 你会看到这个kernel很简化了,没有旋转功能了,只是简单的复制一张图片:读取原图,写入目标图。因为之前的那个旋转kernel的很多特性,例如从归一化的坐标进行插值这些,surface没有。所以这个kernel只是一个简化的什么都不干的kernel,但演示了surface可以直接写入的特性。

(1)更新CUDA Array的时候,texture是只读的,但这个可以对后备存储(CUDA Array)写入。可以用来更新一个CUDA Array给texture用,但需要注意的是,surface写入和texture读取不维持一致性,只有在下次kernel启动的时候才能生效,所以你往往能见到这种风格的代码——stream中:surface写入kernel---->texture读取kernel 这么一个顺序。

(2)你不需要复杂的texture功能,而只需要简单的越界处理(只有两种最简单的边界处理);

(3) 你可能需要surface访问CUDA Array,以便使用里面的特殊的,对用户不透明,但可能对程序性能有提升的存储方式。 大致这三种情况。

还有一点,就是纹理在不使用归一化坐标的时候,坐标的含义是点/元素/纹元。而surface的坐标是字节。里面有个元素大小的倍数差别。从texture改成surface的时候,需要注意这个坐标问题(假设surface能满足要求),其他应当都一样了。以及,刚才说过的不维持读写一致性这个很重要。写入surface必须在下次kernel启动才能生效。立刻读取将导致未定义的结果。

还有一点。surface必须绑定到Cuda array,

struct cudaResourceDesc resDesc; memset(&resDesc, 0, sizeof(resDesc)); resDesc.resType = cudaResourceTypeArray;

这三行代码中的resType,必须是cudaResourceTypeArray。手册没说,但是用线性内存这里会失败的。其实也很好理解。本身surface功能就少。如果再不使用CUDA Array,那就和普通的指针读写普通内存(显存)毫无区别了。(除了唯一剩下的防止越界)。那样的话又何必要用它了。所以这里要求必须的,这里不能使用cudaResourceTypeLinear,而必须是TypeArray。

Surface Reference API——

上面说的这些对object和reference都有效的。他们只是一个是老API,一个是新API而已。无本质区别的,类似texture reference和texture object的关系,纹理的特性是通用的,只是形式不同。surface同理。surface reference就比surface object早出了fermi这一代,从Fermi开始有的surface reference,但从Kepler就立刻更新了, 有了surface object。而texture reference是从一开头有CUDA就有的,不过它们两个都是从Kepler(3.0)开始,更新有了texture object和surface object,所以texture refernce独立存在的时间更长。老代码涉及texture reference的可能要远比surface reference的多。

The following code sample applies some simple transformation kernel to a texture.; 后面的代码没有什么特别的,但需要注意的是,从inputSurfRef读取后,没有经过任何处理,就写入了outputSurfRef。以前texture那段是有个旋转的。这个是原图,完全没转动。但:

(1)虽然没转动,但结果直接写入了一个输出的cuda array, 以后可以直接给需要该cuda array内容的texture用。而之前的例子只能写入普通内存。(因为texture无写入能力)

(2)这里没有使用outputSurfRef。如果要使用的话,必须在下次的kernel中才能使用它,本次如果使用了会导致未定义的结果。

(3)注意x坐标是一个乘以了4(元素大小)的整数。因为单位是字节。 而之前的texture坐标不需要*4, 同时是归一化的浮点值[0.0, 1.0)。

归一化的浮点坐标,这个属于texture独有的高级特性。不能使用的。(但可以自行用代码实现坐标变换,等效的实现这一点,只是不能自动免费实现了)

有不明白的地方,请在本文后留言

或者在我们的技术论坛bbs.gpuworld.cn上发帖

原文发布于微信公众号 - 吉浦迅科技(gpusolution)

原文发表时间:2018-05-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏用户画像

H5 新增的input元素的类型

search类型用于搜索域,如站点搜索或Google搜索。search域显示为常规的文本域。

713
来自专栏java系列博客

深入理解Java内存模型(七)——总结

1703
来自专栏北京马哥教育

Python入门之生成海贼王云图

本教程适合于有一定编程经验的同学,使用Python3,在Jupyter进行调试开发。 涉及的Python基础包括: 变量和函数的定义和使用 列表和字典等数据结构...

34910
来自专栏吉浦迅科技

TensorFlow版本号升至1.0,正式版即将到来

2015年11月份,谷歌宣布开源了深度学习框架TensorFlow,一年之后,TensorFlow就已经成长为了GitHub上最受欢迎的深度学习框架,尽管那时候...

3779
来自专栏程序员的诗和远方

30分钟QUnit入门教程

30分钟让你了解Javascript单元测试框架QUnit,并能在程序中使用。 QUnit是什么 QUnit是一个强大,易用的JavaScript单元测试框架,...

5399
来自专栏java系列博客

UML——序列图

2124
来自专栏SDNLAB

码农学ODL之Toaster代码解析

Toaster(烤面包机)是OpenDaylight的一个例子,该例子的目的不是让你如何烤面包,而是借这个例子学习OpenDaylight的特性。在Toaste...

4036
来自专栏好好学习吧

vim简单使用教程

vim的学习曲线相当的大(参看各种文本编辑器的学习曲线),所以,如果你一开始看到的是一大堆VIM的命令分类,你一定会对这个编辑器失去兴趣的。下面的文章翻译自《L...

1453
来自专栏奇点大数据

【干货】Pytorch中的DataLoader的相关记录

DataLoader简单介绍 DataLoader是Pytorch中用来处理模型输入数据的一个工具类。通过使用DataLoader,我们可以方便地对数据进行...

1.6K6
来自专栏为数不多的Android技巧

ASCII Art:使用纯文本流程图

我们使用纯文本写代码,有了Markdown又可以使用纯文本写文档,那么对于更直观的信息表达方式——图片,能不能使用纯文本描述呢?

3412

扫码关注云+社区

领取腾讯云代金券