- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设我有这个玩具代码:
#define N (1024*1024)
#define M (1000000)
__global__ void cudakernel1(float *buf)
{
int i = threadIdx.x + blockIdx.x * blockDim.x;
buf[i] = 1.0f * i / N;
for(int j = 0; j < M; j++)
buf[i] *= buf[i];
}
__global__ void cudakernel2(float *buf)
{
int i = threadIdx.x + blockIdx.x * blockDim.x;
for(int j = 0; j < M; j++)
buf[i] += buf[i];
}
int main()
{
float data[N];
float *d_data;
cudaMalloc(&d_data, N * sizeof(float));
cudakernel1<<<N/256, 256>>>(d_data);
cudakernel2<<<N/256, 256>>>(d_data);
cudaMemcpy(data, d_data, N * sizeof(float), cudaMemcpyDeviceToHost);
cudaFree(d_data);
}
我可以像这样合并两个内核吗:
#define N (1024*1024)
#define M (1000000)
__global__ void cudakernel1_plus_2(float *buf)
{
int i = threadIdx.x + blockIdx.x * blockDim.x;
buf[i] = 1.0f * i / N;
for(int j = 0; j < M; j++)
buf[i] *= buf[i];
__syncthreads();
for(int j = 0; j < M; j++)
buf[i] += buf[i];
}
int main()
{
float data[N];
float *d_data;
cudaMalloc(&d_data, N * sizeof(float));
cudakernel1_plus_2<<<N/256, 256>>>(d_data);
cudaMemcpy(data, d_data, N * sizeof(float), cudaMemcpyDeviceToHost);
cudaFree(d_data);
}
一般情况下,两个采用相同 block 和线程参数的连续内核可以与中间__syncthreads()
合并吗?
(我的真实情况是 6 个连续的非平凡内核,它们有很多设置和拆卸开销)。
最佳答案
最简单、最普遍的答案是否定的。我只需要找到一个范式被打破的例子来支持这一点。让我们提醒自己:
__syncthreads()
是 block 级执行屏障,但不是设备范围的执行屏障。唯一定义的设备范围执行障碍是内核启动(假设我们正在讨论将内核发布到同一流中,以便顺序执行)。
特定内核启动的线程 block 可以以任何顺序执行。
假设我们有两个函数:
让我们假设 vector 反转不是就地操作(输出与输入不同),并且每个线程 block 处理一个 block 大小的 vector block ,读取元素并存储到适当的位置输出 vector 。
为了简单起见,我们假设我们只有(需要)两个线程 block 。对于第一步, block 0 将 vector 的左侧复制到右侧(顺序颠倒), block 1 从右到左复制:
1 2 3 4 5 6 7 8
|blk 0 |blk 1 |
\ | /
X
/| \
v | v
8 7 6 5 4 3 2 1
对于第二步,在经典的并行归约方式中, block 0 对输出 vector 的左侧元素求和, block 1 对右侧元素求和:
8 7 6 5 4 3 2 1
\ / \ /
blk0 blk1
26 10
只要第一个函数在 kernel1 中发布,第二个函数在 kernel2 中发布,在 kernel1 之后进入同一个流,这一切都可以正常工作。对于每个内核, block 0 是否在 block 1 之前执行都没有关系,反之亦然。
如果我们组合这些操作以便我们有一个内核,并且 block 0 将 vector 的前半部分复制/反转到输出 vector 的后半部分,然后执行 __syncthreads()
,然后对输出 vector 的前半部分求和,事情很可能会中断。如果 block 0 在 block 1 之前执行,那么第一步会很好( vector 的复制/反转)但第二步将对尚未填充的输出数组一半进行操作,因为block 1 还没有开始执行。计算出的总和将是错误的。
在不尝试给出正式证据的情况下,我们可以看到在上述情况下,数据从一个 block 的“域”移动到另一个 block 的“域”,我们冒着破坏事物的风险,因为之前的设备范围同步(内核启动)对于正确性是必要的。但是,如果我们可以限制 block 的“域”,以便后续操作消耗的任何数据仅由该 block 中的先前操作产生,那么 __syncthreads()
可能足以让这个策略正确。 (前面的愚蠢示例可以很容易地重新设计以实现这一点,只需让 block 0 负责输出 vector 的前半部分,从而从 后半部分复制输入 vector ,反之亦然。)
最后,如果我们将数据范围限制为单个线程,那么我们甚至可以在不使用 __syncthreads()
的情况下进行此类组合。后两种情况可能具有“令人尴尬的并行”问题的特征,表现出高度的独立性。
关于c++ - 可以使用 __syncthreads() 合并单独的 CUDA 内核吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38755356/
我有几个长度不等的 vector ,我想对其进行cbind。我将 vector 放入列表中,并尝试结合使用do.call(cbind, ...): nm <- list(1:8, 3:8, 1:5)
合并(合并)两个 JSONObjects 的最佳方式是什么? JSONObject o1 = { "one": "1", "two": "2", "three": "3" }
我在一个表中有许多空间实体,其中有一个名为 Boundaries 的 geometry 字段。我想生成一个具有简化形状/几何图形的 GeoJson 文件。 这是我的第一次尝试: var entitie
谁能说出为什么这个选择返回 3.0 而不是 3.5: SELECT coalesce(1.0*(7/2),0) as foo 这个返回 3: SELECT coalesce(7/2,0) as foo
首先抱歉,也许这个问题已经提出,但我找不到任何可以帮助我的东西,可能是因为我对 XSLT 缺乏了解。 我有以下 XML: 0 OK
有时用户会使用 Windows 资源管理器复制文件并在他们应该执行 svn 存储库级别的复制或合并时提交它们。因此,SVN 没有正确跟踪这些变化。一旦我发现这一点,损坏显然已经完成,并且可能已经对相关
我想组合/堆叠 2 个不同列的值并获得唯一值。 如果范围相邻,则可以正常工作。例如: =UNIQUE(FILTERXML(""&SUBSTITUTE(TEXTJOIN(",",TRUE,TRANSPO
使用iTextSharp,如何将多个PDF合并为一个PDF,而又不丢失每个PDF中的“表单字段”及其属性? (我希望有一个使用来自数据库的流的示例,但文件系统也可以) 我发现this code可以正常
是否有一个合并函数可以优先考虑公共(public)变量中的非缺失值? 考虑以下示例。 首先,我们生成两个 data.frames,它们具有相同的 ID,但在特定变量上有互补的缺失值: set.seed
我们正在尝试实现 ALM Rangers 在最新的 Visual Studio TFS Branching and Merging Guide 中描述的“基本双分支计划”。 .从指导: The bas
我在不同目录(3个不同名称)中有很多(3个只是一个例子)文本文件,如下所示: 目录:A,文件名:run.txt 格式:txt制表符分隔 ; file one 10 0.2 0.5 0.
我有一张包含学生等级关系的表: Student Grade StartDate EndDate 1 1 09/01/2009 NULL 2
我在学习 https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/working-with-associatio
我觉得我有世界上最简单的 SVN 用例: 我有一个文件,Test.java在 trunk SVN的。 我分行trunk至 dev-branch . 我搬家Test.java进入 com/mycompa
我有两个数据框,其中一些列名称相同,而另一些列名称不同。数据框看起来像这样: df1 ID hello world hockey soccer 1 1 NA NA
Elasticsearch 中是否缺少以扁平化形式(多个子/子aggs)返回结果的方法? 例如,当前我正在尝试获取所有产品类型及其状态(在线/离线)。 这就是我最终得到的: aggs [ { key:
如何合并如下所示的 map : Map1 = Map(1 -> Class1(1), 2 -> Class1(2)) Map2 = Map(2 -> Class2(1), 3 -> Class2(2)
我试图通过从netezza服务器导入数据来合并两个数据集。 以下是数据集,其数字为,ID为,字母为,名称为: 下表都是使用命令从netezza导入的: sqoop import --connect n
我有两个数组 $array1 = array('first', 'second', 'third', 'fourth'); $array2 = array('first', 'third', 'fou
我正在 SQL Server 中运行合并。在我的更新中,我只想在值发生更改时更新该行。有一个版本行在每次更新时都会递增。下面是一个例子: MERGE Employee as tgt USING (SE
我是一名优秀的程序员,十分优秀!