C++ Cuda纹理缓存未在每次内核启动时刷新

C++ Cuda纹理缓存未在每次内核启动时刷新,c++,cuda,textures,texture2d,C++,Cuda,Textures,Texture2d,我正在尝试在CUDA中使用纹理记忆。我编写了一个简单的代码来使用2D纹理添加数字。有一个for循环将内核重复多次。但奇怪的是,纹理缓存似乎只在大约每两次内核启动时刷新一次 内核很简单 _global__ void add(float *f, float *fn){ int y = threadIdx.x; int x = blockIdx.x; float a = tex2D(text,x,y); if (x==1 && y==0){ printf("The

我正在尝试在CUDA中使用纹理记忆。我编写了一个简单的代码来使用2D纹理添加数字。有一个for循环将内核重复多次。但奇怪的是,纹理缓存似乎只在大约每两次内核启动时刷新一次

内核很简单

_global__ void add(float *f, float *fn){
int y = threadIdx.x;
int x = blockIdx.x;

float a = tex2D(text,x,y);
if (x==1 && y==0){
    printf("The location is : %d %d %d\n", x,y,x+nx*y);
    printf("The first element read through texture is : %f\n", a );
    printf("The first element read through global is : %f\n", f[x+nx*y]);
    printf("Printing to :%p\n", f);
}
a+=a;

fn[x+nx*y] = a; }
纹理变量全局定义为

texture<float,2> text;
指针交换没有任何问题,通过全局内存的访问总是给出正确的答案。但在我看来,纹理缓存没有刷新,导致它获取旧值


有人遇到过这个问题吗?我很确定我做错了什么。任何帮助都会非常有用

这里的问题是,当您进行指针交换时,纹理一旦绑定,就不会在两个指针之间交替

由于纹理通过值而不是引用绑定到
f
,因此指针交换对纹理绑定到的内容没有影响。第一次运行内核时,对
fn
的更新对纹理没有影响。然后,当您第二次运行内核时,尽管您交换了指针,但纹理仍指向上一个
f
数组,该数组未被上一个内核调用修改。因此,在第二次内核迭代中,纹理值似乎是相同的,因为它是。如果您希望在每次迭代时更改纹理,则存在逻辑代码设计缺陷

一个可能的“修复”可能是在每一步重新绑定纹理

然而,我不会建议这种“修复”。从内核写入与纹理相关联的绑定线性内存可能会导致未定义的行为。纹理只是一个具有插入缓存的内存区域。纹理内存应该是内核代码的只读内存,因此缓存总是一致的。如果写入底层内存,缓存可能不再连贯

对于希望从内核代码“写入纹理”的情况,建议使用曲面。有很多例子可以证明这一点


此外,一般建议从使用绑定纹理(或曲面)引用切换到无绑定纹理(或曲面)对象,如中所述。

由于纹理是通过值而不是通过引用绑定到
f
的,因此指针交换对纹理绑定到的对象没有影响。第一次运行内核时,对
fn
的更新对纹理没有影响。然后,当您第二次运行内核时,尽管您交换了指针,但纹理仍指向上一个
f
数组,该数组未被上一个内核调用修改。因此,在第二次内核迭代中,纹理值似乎是相同的,因为它是。如果您期望在每次迭代时纹理发生变化,那么您就有一个逻辑代码设计缺陷,这很有意义。谢谢你的评论。对于我的应用程序,我需要在每次迭代中将输出写回纹理。有没有办法通过引用绑定纹理?否则,我看到的唯一选择就是复制内存本身。我能够通过使用两种纹理并在每次迭代中进行读写切换来解决这个问题。这似乎解决了问题。谢谢你的帮助,你可能想调查CUDA。它们的设计目的是向用户写入。从使用CUDA纹理的CUDA内核写入底层纹理资源被认为会导致未定义的行为。此外,您可能希望切换到纹理/曲面对象,而不是现在使用的参考方法。看,表面看起来正是我要找的。我将努力实现这一点。非常感谢您的帮助和信息。
cudaChannelFormatDesc desc = cudaCreateChannelDesc<float>();
gpuErrchk(cudaBindTexture2D(NULL, text, f, desc, nx, ny, sizeof(float)*nx));
checkerr();
text.addressMode[0] = cudaAddressModeWrap;
text.addressMode[1] = cudaAddressModeWrap;
or (int t=0; t<10; t++){
    cout<<"Iteration : "<<t<<endl;
        add<<<nx,ny>>>(f,fn);
    cudaDeviceSynchronize();
    checkerr();

    cudaMemcpy(h_f,fn,sizeof(float)*nx*ny,cudaMemcpyDeviceToHost);
//checkerr();
    cout<<"In iteration "<<t<<" the texture is pointing to "<<f<<endl;
    swap(f,fn);
for (int i=0; i<nx*ny; i++)
    cout<<h_f[i]<<' ';
cout<<endl;

}
Iteration : 0
The location is : 1 0 1
The first element read through texture is : 1.000000
The first element read through global is : 1.000000
Printing to :0x500a20000
In iteration 0 the texture is pointing to 0x500a20000
Iteration : 1
The location is : 1 0 1
The first element read through texture is : 1.000000
The first element read through global is : 2.000000
Printing to :0x500a20200
In iteration 1 the texture is pointing to 0x500a20200
Iteration : 2
The location is : 1 0 1
The first element read through texture is : 2.000000
The first element read through global is : 2.000000
Printing to :0x500a20000
In iteration 2 the texture is pointing to 0x500a20000
Iteration : 3
The location is : 1 0 1
The first element read through texture is : 2.000000
The first element read through global is : 4.000000
Printing to :0x500a20200
In iteration 3 the texture is pointing to 0x500a20200