- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的CUDA内核的每个实例(即每个线程)都需要三个具有不同类型的私有(private)数组。
例如
__global__ void mykernel() {
type1 a[aLen];
type2 b[bLen];
type3 c[cLen];
...
}
aLen
,
bLen
和
cLen
的长度是动态的。
void caller() {
int threadsPerCUDABlock = ...
int CUDABlocks = ...
int threadMemSize =
aLen*sizeof(type1) + bLen*sizeof(type2) + cLen*sizeof(type3);
int blockMemSize = threadsPerCUDABlock * threadMemSize;
mykernel <<< CUDABlocks, threadsPerCUDABlock, blockMemSize >>>();
}
[ thread0_a, thread0_b, thread0_c, thread1_a, ...]
char
:
mykernel <<< CUDABlocks, threadsPerCUDABlock, blockMemSize >>>(threadMemSize);
__global__ void mykernel(int threadMemSize) {
extern __shared__ char sharedMem[];
char* threadMem = &sharedMem[threadMemSize*threadIdx.x]
type1 *a = (type1*) threadMem;
type2 *b = (type2*) &a[aLen];
type3 *c = (type3*) &b[bLen];
...
}
type1
,
type2
和
type3
类型的大小严格减小。
最佳答案
初步
通常,出于性能原因,人们对GPU计算很感兴趣-使他们的代码运行更快。因此,在尝试做出决策时,我们将以性能为指导。
我认为您在问题中提供的草图中的问题之一就是natural alignment requirement in CUDA之一。选择一个任意指针并将其类型转换为其他类型可能会违反此规定。如果您的代码中存在此类问题,则cuda-memcheck
工具应该能够发现它。
将线程专用数组放入C++的典型位置是本地内存,我认为CUDA没什么不同。但是,CUDA C++至少不支持variable-length arrays。在您的问题中,您使用共享内存作为代理进行了草绘。您的想法(我假设)的含义之一是,尽管在编译时不知道这些数组的大小,但是必须有一个大小上限,因为共享内存可能会限制每个线程块低至48KB。因此,如果线程块中有1024个线程,则每个线程的最大组合数组大小将限制为48个字节。每个块有512个线程,可以想象每个线程有96个字节。如果使用共享内存,则可能是由于共享内存限制所致。
因此,另一种方法(如果您可以遵守这些下限)将是简单地上限所需的本地内存,并为每个线程静态定义该大小(或3)的本地内存数组。如已经提到的,必须将单个阵列划分在各个阵列之间,并注意对齐。但是考虑到您的方法建议的小尺寸(例如,总共约96个字节),仅使用上限固定大小的本地数组(而不是共享内存)可能会很方便。
CUDA中的本地内存最终由与全局内存相同的物理资源(GPU DRAM内存)支持。然而,这种安排是这样的,如果每个线程正在访问其自己的本地存储器中的特定元素,那么如果该访问需要由DRAM服务,则线程间的影响将等同于合并访问。这意味着每线程本地存储以某种方式是交错的。如果出于性能考虑,如果我们提出自己的可变长度数组实现,那么这个交织特性也是我们要注意的。它同样适用于全局内存代理(以启用合并)或共享内存代理(以避免存储区冲突)。
除了出于性能原因而希望交织访问之外,而不是倾向于使用共享内存的可能的性能原因是共享内存的广泛使用可能会对占用率以及性能产生负面影响。该主题在其他许多地方都有介绍,因此在此不再赘述。
实现
本地记忆
如上所述,我认为关于使用共享内存的建议的一个隐含假设是,所需数组的实际大小必须有一些(合理较小)上限。如果是这种情况,最好使用3个分配了上限大小的数组:
const int Max_aLen = 9;
const int Max_bLen = 5;
const int Max_cLen = 9;
__global__ void mykernel() {
type1 a[Max_aLen];
type2 b[Max_bLen];
type3 c[Max_cLen];
...
}
cudaMalloc
,我们可以分别处理单独的数组,并且我们对对齐要求的关注相对较少。由于我们假装将这些全局数组当作线程专用来使用,因此我们将希望安排索引以创建每个线程的交错存储/访问,这将有助于合并。对于您的3数组示例,它可能看起来像这样:
#include <stdio.h>
typedef unsigned type1;
typedef char type2;
typedef double type3;
__global__ void mykernel(type1 *a, type2 *b, type3 *c) {
size_t stride = (size_t)gridDim.x * blockDim.x;
size_t idx = (size_t)blockIdx.x*blockDim.x+threadIdx.x;
a[7*stride+idx] = 4; // "local" access to a
b[0*stride+idx] = '0'; // "local" access to b
c[3*stride+idx] = 1.0; // "local" access to c
}
int main(){
// 1D example
type1 *d_a;
type2 *d_b;
type3 *d_c;
// some arbitrary choices to be made at run-time
size_t alen = 27;
size_t blen = 55;
size_t clen = 99;
int nTPB = 256;
int nBLK = 768;
size_t grid = (size_t)nBLK*nTPB;
// allocate
cudaMalloc(&d_a, alen*grid*sizeof(type1));
cudaMalloc(&d_b, blen*grid*sizeof(type2));
cudaMalloc(&d_c, clen*grid*sizeof(type3));
// launch
mykernel<<<nBLK, nTPB>>>(d_a, d_b, d_c);
cudaDeviceSynchronize();
}
#include <stdio.h>
typedef unsigned type1;
typedef char type2;
typedef double type3;
__global__ void mykernel(int b_round_up, int c_round_up) {
extern __shared__ char sdata[];
type1 *a = (type1 *)sdata;
type2 *b = (type2 *)(sdata + b_round_up);
type3 *c = (type3 *)(sdata + c_round_up);
size_t stride = blockDim.x;
size_t idx = threadIdx.x;
a[7*stride+idx] = 4; // "local" access to a
b[0*stride+idx] = '0'; // "local" access to b
c[3*stride+idx] = 1.0; // "local" access to c
}
int main(){
// 1D example
// some arbitrary choices to be made at run-time
int alen = 9;
int blen = 5;
int clen = 9;
int nTPB = 256;
int nBLK = 1;
// calculate aligned shared mem offsets
int b_round_up = (((nTPB*alen*sizeof(type1) + sizeof(type2)-1)/sizeof(type2))*sizeof(type2)); // round up
int c_round_up = (((b_round_up + nTPB*blen*sizeof(type2) + sizeof(type3)-1)/sizeof(type3))*sizeof(type3)); // round up
// allocate + launch
mykernel<<<nBLK, nTPB, c_round_up + nTPB*clen*sizeof(type3)>>>(b_round_up,c_round_up);
cudaDeviceSynchronize();
}
关于c++ - 具有不同类型的CUDA每线程阵列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56564159/
我有一个关于将字符串分配给数组编号的问题。 我已经声明了字符串数组,例如。 String[] answer = {"yes", "no", "maybe"}; 如何在不使用这种方法的情况下将每个字符串
我正在为云数据库使用 Firebase 编写一个 Android 应用程序。它基本上是一个多项选择调查问题应用程序。导入到我的 Firebase { "multiple_choice" : {
我想将输入文件中的以下行存储到 3D 数组中(不包括第一行。)第一行表示后续行的数量。 3 4 9368 86 843 23224 4 7323 2 2665 2665 8447 47 843 527
这是我关于容器的小大问题,尤其是数组。 我正在编写一个物理代码,主要操纵一大组(> 1 000 000)“粒子”(每个粒子有 6 个 double 坐标)。我正在寻找最佳方式(在性能方面)来实现一个类
我有一个超链接,我需要在 Angular 4 中创建一个路由器链接。我有很多部分指向 url,其中一部分是一个数组。我不确定如何让数组将自己拆分成 routerlink 数组的部分。 以这个人为的例子
大家好,我有一个轮子选择器在工作,但目前它正在为所有轮子提取 0-9 的数字。我希望能够设置值而不是 0-9 我希望它是从数组或字符串中提取的单词,所以我可以输入它们 myslef 因为我不确定目前从
我正在尝试使用 Spotify API 并进入数组。 const App = () => { const [isLoading, setIsLoading] = useState(true);
我尝试创建 Tic Tac Toe,我能够填满我的棋盘,并且能够检查行和列以确定谁获胜。然而,我需要一些帮助来检查对角线,看看谁赢了。这是我到目前为止所拥有的。我是初学者,所以请不要让代码太难。 检查
--in the package type t_array is array (natural range <>) of std_logic_vector (7 downto 0); type p_a
我在访问字符串数组时遇到困难。它被声明为私有(private)数组并填充在类的构造函数中。我定义了一个 Get 函数。问题是当我在编译时调用此函数时出现错误,提示我无法访问在类中声明的私有(priva
无法弄清楚推送到 Moose 数组的语法(我确信这很明显,而且我很愚蠢)。这是 this question 的延续.在我看来,对于我的具体情况,我需要的不仅仅是一个简单的值。尝试使用 Moose 式的
我有一个 3d 数组,我正在尝试从中获取刺伤列表。换句话说,给定数组: t = np.array([[[1,2],[3,4]],[[5,6],[7,8]],[[9,10],[11,12]]]) arr
我正在寻找绘制一个 3 维数组。有没有一种方法可以直接输入数组,绘制体素并在 3d 数组中的位置产生的坐标处绘制实际值(颜色)?到目前为止我发现的所有方法(例如 ax.voxels、mlab.poin
我正在尝试使用 Knockout 创建一个简单的电子表格。我试图让每个单元格都可观察,以便在发生变化时,我可以评估值并进行相应的计算。因此,如果他们在单元格中输入 6+7,我可以评估并将该值更改为总数
我有当前时间和这组时间。我想计算出下一次与当前时间最接近的时间。 let date = NSDate() let calendar = NSCalendar.currentCalendar() let
我想在我的小程序中创建一个二维图像数组。我需要一个 4x4 网格,其中有 4 个图像,每个图像 4 个随机分布在阵列中。这里有一些答案,但我不明白如何使用它们。 最佳答案 您可以声明 Image[][
基本上,此代码列出了“可用”挑战,其中 complete = 0 并在每个列表中都有一个接受submit 按钮。到目前为止,我一次只能列出一项,因为列出的多个按钮无法识别匹配 ID $echo 任何人
我正在尝试创建一个带有动态变量的过滤数组。我创建一个包含过滤器键的数组,然后创建一个过滤后的数组,该数组只应返回与第一个数组中的键匹配的项目。 带有过滤器键的数组:$scope.participant
我是一个相对年轻的开发人员,我对一些事情感到困惑。 这是我的代码: function pairElement(str) { var arr = []; var pairs = [
我正在 Angular 中创建一个函数,我想抓取所有博客文章,其类别与单击的按钮相匹配,我的 Firebase 中有 3 个不同的字段,标题为类别 1、类别 2 和类别 3。例如,当用户单击新闻通讯时
我是一名优秀的程序员,十分优秀!