我想实现一个cuda函数'add(a,b,c)',用于将两个单通道浮点图像'a'和'b'加在一起,并将结果存储在浮点中点图像'c'。所以'c = a + b'。 该函数将通过首先将纹理对象'aTex'和'bTex'绑定到音高线性图像'a'和'b',然后仅访问内核中的图像'a'和'b'来实现。 通过纹理对象'aTex'和'bTex'。总和通过简单写入全局存储器存储在'c'中。 如果我通过'b'调用递增'a'的函数,现在会发生什么 - 所以我称之为'add(a,b,a)'?因为现在,图像'a'在两个地方的内核中使用 - 从'a'我通过纹理对象'aTex'读取值,我也存储值在'a'中通过写入全局内存。是否可能使用'add'函数会导致错误的结果?
答案 0 :(得分:3)
GPU的纹理不连贯。这意味着在对该相同位置的后续纹理访问期间,可以或可以不反映全局存储器写入纹理下面的全局存储器的特定位置。因此在这种情况下存在写后读写危险。
但是,如果代码执行全局内存写入纹理下面的全局内存的特定位置,并且随后在内核的生命周期内不会通过纹理读取该位置,没有写后读写危险,代码将按预期运行:全局内存中的更新数据可以由后续内核以任何所需方式访问,包括纹理访问,因为纹理缓存在内核上清除发射。
由于纹理读取路径提供了更高的负载性能,我个人使用这种方法以小步幅加速就地操作。一个例子是CUBLAS中的BLAS-1操作[D | S | Z | C] SCAL,它用标量缩放每个数组元素。