CUDA学习(八十七)

简介:

独立的线程调度:
Volta体系结构在变形中的线程之间引入了独立线程调度功能,可实现先前不可用的内部变形同步模式,并在移植CPU代码时简化代码更改。 但是,如果开发人员对以前的硬件体系结构的同步性做出假设,这可能会导致参与执行的代码的一组相当不同的线程。
以下是关注的代码模式,并提出了针对Volta安全代码的纠正措施:
1.对于使用warp内在函数(__shfl *__any__all__ballot)的应用程序,开发人员必须使用* _sync后缀将代码移植到新的,安全的同步对象。 新的扭曲内在函数需要一个线程掩码来明确定义哪些通道(warp的线程)必须参与warp内在。 有关详细信息,请参阅变形表决函数和变形混合函数。
由于CUDA 9.0+提供了内在函数,因此可以使用以下预处理器宏有条件地执行代码(如有必要):

#if defined(CUDART_VERSION) && CUDART_VERSION >= 9000
// *_sync intrinsic
#endif

这些内在函数在所有体系结构上都可用,不仅仅是Volta,在大多数情况下,单个代码库就足以适用于所有体系结构。 但是,请注意,对于Pascal和更早的体系结构,掩码中的所有线程必须在收敛中执行相同的warp内部指令,并且掩码中所有值的并集必须与warp的活动掩码相等。 以下代码模式在Volta上有效,但不在Pascal或更早版本的体系结构上。

if (tid % warpSize < 16) {
    ...
        float swapped = __shfl_xor_sync(0xffffffff, val, 16);
    ...
}
else {
    ...
        float swapped = __shfl_xor_sync(0xffffffff, val, 16);
    ...
}

__ballot(1)的替换是__activemask()。 请注意,即使在单个代码路径内,warp内的线程也可能会发散。 因此,__activemask()__ballot(1)可能只返回当前代码路径上的线程子集。 以下无效代码示例在data [i]大于阈值时将输出的位i设置为1。 __activemask()用于尝试启用dataLen不是32的倍数的情况。

// Sets bit in output[] to 1 if the correspond element in data[i]
// is greater than ‘threshold’, using 32 threads in a warp.
for (int i = warpLane; i<dataLen; i += warpSize) {
    unsigned active = __activemask();
    unsigned bitPack = __ballot_sync(active, data[i] > threshold);
    if (warpLane == 0)
        output[i / 32] = bitPack;
}

此代码无效,因为CUDA不保证仅在循环条件下变形才会发生变化。 当由于其他原因发生分歧时,将通过变形中的不同线程子集针对相同的32位输出元素计算冲突结果。 正确的代码可能会使用非发散循环条件和__ballot_sync()一起安全地枚举参与阈值计算的warp中的线程集合,如下所示:

for (int i = warpLane; i - warpLane<dataLen; i += warpSize) {
    unsigned active = __ballot_sync(0xFFFFFFFF, i < dataLen);
    if (i < dataLen) {
        unsigned bitPack = __ballot_sync(active, data[i] > threshold);
        if (warpLane == 0)
            output[i / 32] = bitPack;
    }
}

2.如果应用程序具有warp同步代码,则它们将需要在通过全局或共享内存在线程之间交换数据的任何步骤之间插入新的__syncwarp()全范围屏障同步指令。 代码以锁步执行的假设或从单独线程读取/写入的假设在整个变形中都是可见的,而不同步是无效的。

float s_buff[tid] = val;
__syncthreads();
// Inter-warp reduction
for (int i = BSIZE / 2; i>32; i /= 2) {
    s_buff[tid] += s_buff[tid + i];
    __syncthreads();
}
// Intra-warp reduction
// Butterfly reduction simplifies syncwarp mask
if (tid < 32) {
    float temp;
    temp = s_buff[tid ^ 16]; __syncwarp();
    s_buff[tid] += temp; __syncwarp();
    temp = s_buff[tid ^ 8]; __syncwarp();
    s_buff[tid] += temp; __syncwarp();
    temp = s_buff[tid ^ 4]; __syncwarp();
    s_buff[tid] += temp; __syncwarp();
    temp = s_buff[tid ^ 2]; __syncwarp();
    s_buff[tid] += temp; __syncwarp();
}
if (tid == 0) {
    *output = s_buff[0] + s_buff[1];
}
__syncthreads()

timg

目录
相关文章
|
数据可视化 算法 定位技术
SWMM从入门到实践教程 01 SWMM软件介绍
SWMM(Storm Water Management Model)是一款用于城市暴雨径流模拟和城市雨水管理的计算机软件。SWMM软件最初由美国环保局(EPA)开发,现在已经成为一个广泛使用的软件,用于设计、规划和管理城市排水系统。
|
缓存 Kubernetes 网络协议
阿里云DNS常见问题之在手机上使用阿里的私人dns失败如何解决
阿里云DNS(Domain Name System)服务是一个高可用和可扩展的云端DNS服务,用于将域名转换为IP地址,从而让用户能够通过域名访问云端资源。以下是一些关于阿里云DNS服务的常见问题合集:
|
3月前
|
人工智能 API 开发者
重磅官宣!阿里云百炼Coding Plan四大模型齐上线,7.9元就能用顶配
阿里云百炼Coding Plan上线Qwen3.5、GLM-5、MiniMax M2.5、Kimi K2.5四大顶尖开源模型,支持Qwen Code等工具自由切换。Lite套餐首月7.9元(1.8万次请求),Pro仅39.9元(9万次),大幅降低开发成本。
|
数据采集 人工智能 自然语言处理
阶跃星辰联合光影焕像开源 3D 大模型 Step1X-3D,高保真+可控!
阶跃星辰联合光影焕像开源 3D 大模型 Step1X-3D,高保真+可控!
441 4
|
机器学习/深度学习 存储 缓存
ORCA:基于持续批处理的LLM推理性能优化技术详解
大语言模型(LLMs)的批处理优化面临诸多挑战,尤其是由于推理过程的迭代性导致的资源利用不均问题。ORCA系统通过引入迭代级调度和选择性批处理技术,有效解决了这些问题,大幅提高了GPU资源利用率和系统吞吐量,相比FasterTransformer实现了最高37倍的性能提升。
892 26
|
供应链 算法 调度
【双层模型】考虑供需双侧的综合能源双层优化模型
该程序构建了一个综合能源系统的优化调度双层模型,采用差分进化算法和规划算法分别求解上下层问题。模型涵盖了燃气轮机、锅炉、风电、光伏及储能设备的协同运行,并考虑了供应商与用户的利益平衡。通过满足设备出力、储能、负荷平衡等约束条件,实现了系统经济性和性能的优化。程序基于Matlab+Cplex编写,注释详尽且附带文档说明,便于学习研究。
|
数据采集 存储 JSON
C语言如何执行HTTP GET请求
C语言如何执行HTTP GET请求
|
Prometheus Kubernetes Cloud Native
k8s安装kube-promethues(超详细)
k8s安装kube-promethues(超详细)
2136 0
|
SQL 数据挖掘
SQLBolt,一个练习SQL的宝藏网站
SQLBolt,一个练习SQL的宝藏网站
836 0
|
存储 缓存 编译器
探秘C++中的神奇组合:std--pair的魅力之旅
探秘C++中的神奇组合:std--pair的魅力之旅
1241 1
探秘C++中的神奇组合:std--pair的魅力之旅