我试图通过使用常量参数但获得错误来分配共享内存.我的内核看起来像这样:
__global__ void Kernel(const int count)
{
__shared__ int a[count];
}
Run Code Online (Sandbox Code Playgroud)
我收到一个错误说
错误:表达式必须具有常量值
伯爵是常量!为什么我收到此错误?我怎么能绕过这个?
在当今的大多数nVIDIA GPU上,共享内存的大小(OpenCL术语中的"本地内存")仅为16 KiB.
我有一个应用程序,我需要创建一个具有10,000个整数的数组.所以我需要适应10,000个整数的内存量= 10,000*4b = 40kb.
我只发现本地内存比寄存器内存慢,每个线程两种类型.
共享内存应该很快,但它比[线程]的本地内存更快?
我想要做的是一种中值滤波器,但具有给定的百分位数而不是中位数.因此,我需要获取列表的块,对它们进行排序,然后选择一个合适的列表.但我无法开始对共享内存列表进行排序或出现问题.只要复制到本地内存,我会失去很多性能吗?
今天我__local
向我的内核添加了四个变量以转储中间结果.但是只需将四个以上的变量添加到内核的签名中并添加相应的内核参数,就会将内核的所有输出都呈现为"0".没有cl函数返回错误代码.
我进一步尝试只添加两个较小的变量之一.如果我只添加其中一个,它可以工作,但如果我添加它们,它就会崩溃.
那么OpenCL的这种行为是否意味着我分配给了大量__local
内存?我怎么知道,我可以__local
使用多少内存?
我目前正在研究CUDA,了解到有全局内存和共享内存。
我查看了CUDA文档,发现GPU可以分别使用ld.shared
/st.shared
和ld.global
/st.global
指令访问共享内存和全局内存。
我好奇的是用什么指令将数据从全局内存加载到共享内存?
如果有人能让我知道那就太好了。
谢谢!
__global__ void my_function(int* global_mem)
{
__shared__ int shared_mem[10];
for(int i = 0; i < 10; i++) {
shared_mem[i] = global_mem[i]; // What instrcuton is used for this load operation?
}
}
Run Code Online (Sandbox Code Playgroud) __shared__
CUDA中的内存似乎在编译时需要已知的大小.但是,在我的问题中,__shared__
内存大小只在运行时知道,即
int size=get_size();
__shared__ mem[size];
Run Code Online (Sandbox Code Playgroud)
这将最终导致"错误:常数值未知",我不知道如何解决这个问题.
假设我们有一个数组int * data
,每个线程将访问该数组的一个元素.由于此数组将在所有线程之间共享,因此它将保存在全局内存中.
让我们创建一个测试内核:
__global__ void test(int *data, int a, int b, int c){ ... }
Run Code Online (Sandbox Code Playgroud)
我确定data
数组将在全局内存中,因为我使用了为这个数组分配了内存cudaMalloc
.至于其他变量,我已经看到一些传递整数而不分配内存的例子,立即到内核函数.在我的情况下,这些变量是a
b
和c
.
如果我没有记错的话,即使我们不直接调用cudaMalloc
分配4个字节为每三个整数,CUDA会自动为我们做,所以最后的变数a
b
和c
将在全球内存中分配.
现在这些变量只是辅助的,线程只读取它们而没有别的.
我的问题是,将这些变量传输到共享内存不是更好吗?
我想如果我们有例如10
带有1024
线程的块,我们需要10*3 = 30
读取4
字节以便将数字存储在每个块的共享内存中.
如果没有共享内存,并且每个线程必须读取所有这三个变量一次,那么全局内存读取的总量将1024*10*3 = 30720
是非常低效的.
现在,这里的问题是,我有点新的CUDA和我不知道是否有可能转移内存变量a
b
和c
每个块的共享内存,而不必每个线程从全局存储器读取这些变量并加载它们到共享内存,所以最终全局内存读取的总量将是1024*10*3 = 30720
和否10*3 = 30
.
在以下网站上有这个例子:
__global__ void staticReverse(int *d, int n)
{
__shared__ …
Run Code Online (Sandbox Code Playgroud) 我目前正在尝试将 2D 卷积代码从这个问题调整为 3D,但无法理解我的错误在哪里。
我的二维码如下所示:
#include <iostream>
#define MASK_WIDTH 3
#define MASK_RADIUS MASK_WIDTH / 2
#define TILE_WIDTH 8
#define W (TILE_WIDTH + MASK_WIDTH - 1)
/**
* GPU 2D Convolution using shared memory
*/
__global__ void convolution(float *I, float* M, float *P, int width, int height)
{
/***** WRITE TO SHARED MEMORY *****/
__shared__ float N_ds[W][W];
// First batch loading
int dest = threadIdx.x + (threadIdx.y * TILE_WIDTH);
int destY = dest / W;
int destX = dest …
Run Code Online (Sandbox Code Playgroud) 来自 CUDA 编程指南:
[Warp shuffle 函数] 在 warp 内的线程之间交换变量。
我知道这是共享内存的替代方案,因此它被用于扭曲中的线程来“交换”或共享值。但它背后的直觉是什么(它是如何工作的)?与使用共享内存相比,它有什么好处?
在我的 CUDA 应用程序中,我将数据从设备内存复制到共享内存。该数据也缓存在 L1 中吗?