cuda - 在 cuda 中,是否可以从具有预期序列的稀疏数组中写入密集数组?
问题描述
有array1
代表 0 或 1(对于每个线程块):
bool array1[]: [1, 1, 0, 0, 1, 1]
线程块中的每个线程都array1
使用threadIdx.x
.
而且,我需要做shared dense array2 (each value represents thread ID with '1' value from array1
:
__shared__ bool array2[] (thread ID) : [0, 1, 4, 5]
看来,至少,我需要atomicAdd()
对 index 进行操作array2
。
即使有atomicAdd()
,我认为很难array2
像上面的序列
(0, 1, 4, 5)。
是否可以在 cuda 中制作array2
(array1
对于每个线程块)?
解决方案
您可以合并组:
假设读取的布尔值是threasIsIN
:
#include <cooperative_groups.h>
namespace cg = cooperative_groups;
uint32_t tid = threadIdx.x;
const uint32_t warpLength = 32;
uint32_t warpIdx = tid / warpLength;
if (threadIsIn){
auto active = cg::coalesced_threads();
uint32_t idx = active.thread_rank() + warpIdx * warpLength;
array2[idx] = tid;
}
编辑
一个块中有多个warp的解决方案:块的第一个warp将为块中的其余warp准备共享数组,这使得其他warp等待第一个warp完成。
thread_block block = this_thread_block();
uint32_t tid = threadIdx.x;
const uint32_t warpLength = 32;
uint32_t warpIdx = tid / warpLength;
uint32_t startIdx = 0;
uint32_t tidToWrite = tid;
uint32_t maxItr = blockSize / warpLength;
uint32_t itr = 0;
while (warpIdx == 0 && itr < maxItr){
auto warp = cg::coalesced_threads();
auto warpMask = warp.ballot(threadIsIn); // the tid'th bit is set to 1 if threadIsIn is true for tid
uint32_t trueThreadsSize = __popc(warpMask); // counts the number of bits that are set to 1
if(threadIsIn){
auto active = cg::coalesced_threads();
// active.size() has the same value as trueThreadsSize
array2[startIdx + active.thread_rank()] = tidToWrite;
}
startIdx += trueThreadsSize;
tidToWrite += warpLength;
++itr;
arr1Idx += warpLength;
threadIsIn = arr1[arr1Idx];
}
block.sync();
推荐阅读
- php - 如何在laravel中下载上传的文件
- html - 用 100vh 定义的 div 容器的高度太大(看起来它在窗口大小上定位)
- linux - BlueZ:移除与 BLE 设备的绑定不起作用
- cygwin - Cygwin 总是从缓存中安装包
- kubernetes - 当 Pod “忙”时指定给 Kubernetes
- wso2is - 如何使用电子邮件/手机和密码的自定义身份验证?
- flask - 增加 Flask 应用程序的超时设置
- angular - 将访问令牌刷新并保存到会话存储中
- spring-boot - 在 Spring Boot1.5 肥皂后端处理 null vs nil=true
- powerbi - DAX 上年度比较处理的部分数据