在我的 CUDA 应用程序中,我将数据从设备内存复制到共享内存。该数据也缓存在 L1 中吗?
我有一个关于 CUDA C++ 编程的问题。我正在使用共享内存。但我需要更大的共享内存。所以我试图重用共享内存。我的代码是这样的:
__global__ void dist_calculation(...){
..........
{
//1st pass
__shared__ short unsigned int shared_nodes[(number_of_nodes-1)*blocksize];
............
}
{
//2nd pass
__shared__ float s_distance_matrix[(number_of_nodes*(number_of_nodes-1))/2];
........
}
}
Run Code Online (Sandbox Code Playgroud)
共享内存不能同时容纳shared_nodes和s_distance_matrix。但它可以单独容纳每个(我已经测试过)。在第二遍中,程序无法识别 shared_nodes(因为它来自第一遍),但向我显示共享内存没有足够空间的错误。所以看起来,仍然为shared_nodes变量分配了一些空间。有什么方法可以销毁该分配(例如cudaFree)?或任何其他建议?
我有两个 CUDA 内核可以计算类似的东西。一种是使用全局内存(myfun是一种从全局内存读取大量数据并进行计算的设备函数)。第二个内核将该数据块从全局内存传输到共享内存,以便数据可以在块的不同线程之间共享。我使用全局内存的内核比使用共享内存的内核快得多。可能的原因有哪些?
loadArray仅复制d_xto的一小部分m。
__global__ void mykernel(float *d_x, float *d_y, int *d_z, float *d_u, int N, int K, int D)
{
int tid = blockIdx.x*blockDim.x + threadIdx.x;
int index = 0;
float max_s = 1e+37F;
if (tid < N)
{
for (int i = 0; i < K; i++)
{
float s = myfun(&d_x[i*D], d_y, tid);
if (s > max_s)
{
max_s = s;
index = i;
}
}
d_z[tid] = index;
d_u[tid] …Run Code Online (Sandbox Code Playgroud) 我是 CUDA 新手,正在从事个人项目。我知道,如果您想在启动时指定共享内存量:
kernel<<<grid_size,block_size,shared_mem_size>>>(parameters);
Run Code Online (Sandbox Code Playgroud)
另一方面,如果我想将内核放入流中:
kernel<<<grid_size,block_size,0,stream_being_used>>>(parameters);
Run Code Online (Sandbox Code Playgroud)
我不明白为什么第三个参数在流的情况下是0?(我是从 Sanders 和 Kandrot 的《CUDA 示例》第 10 章中得到的)。
如果我想在启动时指定共享内存并将其放入流中,我该如何正确执行此操作?换句话说,中间的参数应该<<<...>>>是什么样的?
我无法找到在 CUDA C 中使用共享内存转置非平方矩阵的方法。(我是 CUDA C 和 C 的新手)
在这篇博客文章中,展示了如何转置矩阵的有效方法(通过共享内存合并转置)。但它只适用于方阵。
github上也提供了代码(与博客上相同)。
StackOverflow 上也有类似的问题。有TILE_DIM = 16设定。但通过该实现,每个线程只需将矩阵的一个元素复制到结果矩阵。
这是我当前的实现:
__global__ void transpose(double* matIn, double* matTran, int n, int m){
__shared__ double tile[TILE_DIM][TILE_DIM];
int i_n = blockIdx.x*TILE_DIM + threadIdx.x;
int i_m = blockIdx.y*TILE_DIM + threadIdx.y; // <- threadIdx.y only between 0 and 7
// Load matrix into tile
// Every Thread loads in this case 4 elements into tile.
int i;
for (i = 0; i < …Run Code Online (Sandbox Code Playgroud) 我想确保我正确理解共享内存中的库冲突。
我有32段数据。
这些段分别由 128 个整数组成。
[[0, 1, ..., 126, 127], [128, 129, ..., 255], ..., [3968, 3969, ..., 4095]]
Run Code Online (Sandbox Code Playgroud)
warp 中的每个线程仅访问其自己的部分。
线程 0 访问对应于索引 0 的部分 0 的位置 0。
线程 1 访问部分 1 上对应于索引 128 的位置 0。
...
线程 31 访问对应于索引 3968 的部分 31 的位置 0。
这是否意味着我有32倍的银行冲突?
如果是,那么如果我向每个段添加一个填充元素(即总共 129 个元素),那么每个线程将访问一个唯一的存储体。我对吗?
我有一个模板定义。隐约类似于以下内容:
template<std::size_t ElemSize>
struct OptimizedArray;
Run Code Online (Sandbox Code Playgroud)
对于这样的东西,为了优化它,我可能会手动将其专门化为 1 字节、2 字节等大小。然而,为了支持 3 个字节,我基本上有另一个模板,如下所示,它编译两个 Size1 和 Size2 数组:
template<size_t ElemSize1, size_t ElemSize2>
struct OptimizedDualArray;
Run Code Online (Sandbox Code Playgroud)
为了使用 3 个字节的 OptimizedArray 接口,我很乐意执行以下操作:
template<>
using OptimizedArray<3> = OptimizedDualArray<1, 2>;
Run Code Online (Sandbox Code Playgroud)
直接说,这个不行。然而,有没有办法做这样的事情呢?
我不明白以下几行到底发生了什么:
unsigned char *membershipChanged = (unsigned char *)sharedMemory;
Run Code Online (Sandbox Code Playgroud)
float *clusters = (float *)(sharedMemory + blockDim.x);
Run Code Online (Sandbox Code Playgroud)
我假设 in #1sharedMemory有效地重命名为membershipChanged,但为什么要将 the 添加blockDim到sharedMemory指针中。这个地址指向哪里?
sharedMemory创建于 extern __shared__ char sharedMemory[];
我在CUDA kmeans 实现中找到的代码。
void find_nearest_cluster(int numCoords,
int numObjs,
int numClusters,
float *objects, // [numCoords][numObjs]
float *deviceClusters, // [numCoords][numClusters]
int *membership, // [numObjs]
int *intermediates)
{
extern __shared__ char sharedMemory[];
// The type chosen for membershipChanged must be large enough to support
// reductions! There are …Run Code Online (Sandbox Code Playgroud) 我有一个长度为128的向量;所有元素在整个计算过程中都是恒定的。
我喜欢在 CUDA 内核中使用这个常量向量。我正在考虑将该向量存储在共享内存中,并在内核中使用它。我想知道该怎么做?几行代码就很好了。
或者这是最好的方法吗?多谢。
我们可以通过全局内存传递头顶:
__global__ void fun(float* a, float* coeff)
{
size_t
i = blockIdx.x * blockDim.x + threadIdx.x;
if (i >= 128)
return;
a[i] *= coeff[i];
}
Run Code Online (Sandbox Code Playgroud)
但这可能不是最好的方法。我想象类似的事情
__shared__ float coeff[128];
Run Code Online (Sandbox Code Playgroud)
但是如何将 CPU 值复制到该共享内存呢?我应该将此共享内存传递给我的内核吗?
假设内核的一个线程尝试更新共享内存中的 4 个不同位置。如果任何其他线程覆盖了这些位置中的任何一个,我是否会导致该操作失败并被逆转?具体来说,这可以原子地执行吗?
mem[a] = x;
mem[b] = y;
mem[c] = z;
mem[d] = w;
Run Code Online (Sandbox Code Playgroud)