GPU的shader分支跳转性能总结

news2024/9/9 0:11:36

引言:

如下的(一)与(二)分别属于uniform branch与宏定义,(一)至始至终是一个固定的值,分支只执行一条而不是既有执行condition ture 也有执行condition false 的情况,(二)使用宏在编译期完成分支跳转,它们两个的性能消耗是怎么样的呢?在很多的博客或者教科书方式的说GPU的跳转分支会中断GPU的并行,会增加耗时等,哪现代的GPU对于分支跳转的性能是怎么样的!作者本人在此做一个总结;
一、

#version 330 core
layout(location = 0) in vec3 aPos;
uniform bool useColorA;
out vec4 vertexColor;
void main()
{
    gl_Position = vec4(aPos, 1.0);
    if (useColorA)
    {
        vertexColor = vec4(1.0, 0.0, 0.0, 1.0); // Red
    }
    else
    {
        vertexColor = vec4(0.0, 0.0, 1.0, 1.0); // Blue
    }
}

二、

#version 330 core
layout(location = 0) in vec3 aPos;
// 宏定义
#define USE_COLOR_A
out vec4 vertexColor;
void main()
{
    gl_Position = vec4(aPos, 1.0);
#ifdef USE_COLOR_A
    vertexColor = vec4(1.0, 0.0, 0.0, 1.0); // Red
#else
    vertexColor = vec4(0.0, 0.0, 1.0, 1.0); // Blue
#endif
}

if-else 分支性能消耗情况:

  1. 现代的 GPU 不管是 PC 端还是移动端对于条件分支 if -else 都有movc/condition move硬件指令优化机制。该指令可以减少由于分支指令引起的pipline暂停和分支预测错误。在这里插入图片描述

如果一个 在Warp(内shader代码指令相同)内所有的线程同时采取同一路径的分支,那么就没有性能损失!或者说分支是基于编译器能够预测优化的uniform变量再或者分支里的操作很简单开销也非常小,以至于可以忽略该开销!(iPhone 在 A8 后都支持movc优化)
2、if 分支只有出现线程分歧 (thread divergency)才会影响GPU并行的性能!在执行同一个warp的线程中有一些满足条件而另一些不满足,则将分别执行代码块A和代码块B。由于SIMD或SIMT的限制,不能同时执行两个代码块,GPU序列化处理这些分支。

  • 所有线程同时执行代码块A,未满足条件的线程暂停。
  • 所有线程完成后,执行代码块B,满足条件的线程暂停。
    案例(三)触发thread divergency
in vec2 TexCoord;
out vec4 FragColor;
// 假设有两个不同的纹理
uniform sampler2D texture1;
uniform sampler2D texture2;
void main()
{
    vec4 color;
    if (TexCoord.x < 0.5)
    {
        color = texture(texture1, TexCoord);
    }
    else
    {
        color = texture(texture2, TexCoord);
    }
    FragColor = color;
}

案例(四)也触发thread divergency

in vec3 FragPos;
in vec3 Normal;
out vec4 FragColor;
uniform vec3 lightPos;
uniform vec3 viewPos;
void main()
{
    vec3 norm = normalize(Normal);
    vec3 lightDir = normalize(lightPos - FragPos);
    vec3 result;
    if (dot(norm, lightDir) > 0.5)      // 基于法线方向选择不同的光照模型
    {
        float diff = max(dot(norm, lightDir), 0.0);  漫反射光照模型
        result = diff * vec3(1.0, 0.5, 0.31); // 硬编码的漫反射颜色
    }
    else
    {
        vec3 viewDir = normalize(viewPos - FragPos);            // Phong 光照模型
        vec3 reflectDir = reflect(-lightDir, norm);
        float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32.0);
        result = (0.5 * vec3(1.0, 0.5, 0.31)) + (spec * vec3(0.5, 0.5, 0.5)); // 漫反射 + 镜面反射
    }
    FragColor = vec4(result, 1.0);
}

在这里插入图片描述
如上图 SM中有8个ALU(Core),由于SIMD/SIMT特性,每个ALU的数据不一样,导致if-else语句在某些ALU中执行的是true分支(黄色),有些ALU执行的是false分支(灰蓝色),这样导致很多ALU的执行周期被浪费掉 (masked out)并且拉长了整个执行周期。最坏的情况,同一个SM中只有1/8(8是同一个SM的线程数,不同架构的GPU有所不同)的利用率。实际上,这意味着即使每个线程只执行其中一个分支,整个Warp需要等待所有分支完成,导致线程分歧。
3、 现代的gpu对于uniform branch都有movc优化分支,如上(1)中提到的只会跑一个路径但是vgpr(Vector General Purpose Registers)你得付出2倍。vgpr 使用率直接影响了GPU能够并发执行的着色器线程的数量,movc 过于复杂要求更多的vgpr来存储临时结果、中间状态和最终输出。导致更长的指令序列,增加执行时间。由于 寄存器占用过多,减少可以同时执行的线程数量, 产生 Register spilling(将寄存器写入主存),综上所述要是movc 后太复杂即便只走一次也影响vgpr从而影响性能!
4、对于uniform branch 推荐使用特化常量(specialization constants),顾名思义特化常量是shader编译器编译阶段已知。展开计算或移除不必要的代码路径,常量的使用有助于减少运行时分支和寄存器的使用,从而提升性能。当然spec const 是对于 vk 在 opengles 中并没有,所以在 GLSL 中只能使用宏来定义实现类似于vk 的spec const 条件语句(不会像(3)上说的有vgpr问题) 。

各大平台实测:

如上提到的根据作者本人的实际测试uniform branch 对于if-else与宏之间的性能差异大致如下:
在这里插入图片描述

综上所述:实测可见条件分支 if -else在uniform branch情况下并不会比宏消耗的更多,所以一开始举例(一)与(二)准确来说是一样的,因为现代的GPU shader有movc/condition move硬件指令优化机制。

VGPR:

居然上面提到了vgpr这里单独讨论一下补一下GPU的寄存器的问题!vgpr(Vector General Purpose Registers)是向量通用寄存器,是 GPU 架构中的一个core重要组成部分,用于存储矢量数据和临时计算结果。矢量寄存器的数量和管理对 GPU 性能有极大影响,尤其在处理并行计算任务时。vgpr 主要用于保存线程执行过程中需要的各种数据,包括顶点属性、纹理坐标和中间计算结果等。
它的数量与其架构和设计紧密相关,不同的芯片厂商和型号会有显著差异。在移动端,高通(Qualcomm)、ARM(Mali)、以及苹果(PowerVR)都是主要厂商,而在 PC 端,AMD 和 NVIDIA 是主要的 GPU 制造商都不同!对于Mali-G77,每个计算核也会拥有几十到几百个 VGPR,这因核数和具体型号不同而异。对于Apple GPU与Qualcomm Adreno GPU 没有公开具体数量我也没找到!预估是上百个到一千之间(移动端的功耗与集成度决定的),但是PC比如之前英伟达的费米架构超过了2W的vgpr!
底下有两篇博客关于VGPR的优化(所以在移动端也不要小瞧if-else增加的2倍vgpr,当然在PC端可以不关系的) Optimizing GPU occupancy and resource usage with large thread groups,与vgpr寄存器的压力 How to reduce register pressure

step、三元运算符的性能消耗情况
一、对于三元运算符"?"它就是一个语法糖,在不同的 shader language等价不同! 在hlsl和cg的三元运算符是和lerp step是等效的 gslsl是if-else 的dynamic branching,详细参考:Shader optimization: Is a ternary operator equivalent to branching?
二、step与 if-else 性能对比,首先不是所有的 step 都能替换 if-else 的,所以只能在能替换的情况下讨论,理论预计step 比 if-else 的非thread divergency(movc)消耗性能要看具体情况,如下unity的例子是优化的 Unity Shader: 优化GPU代码–用step()代替if else等条件语句,如下相对于案例(三)就是一种负优化!因为增加了纹理的采样!2D纹理的采样消耗是增加了一次双线性插值与LDU的花销!!!

in vec2 TexCoord;
out vec4 FragColor;
uniform sampler2D texture1;
uniform sampler2D texture2;
void main()
{
    float condition = step(0.5, TexCoord.x);
    vec4 color1 = texture(texture1, TexCoord);
    vec4 color2 = texture(texture2, TexCoord);
   
    // 使用混合来避免 if-else
    vec4 color = mix(color1, color2, condition);
    FragColor = color;
}

建议:

  1. 尽量不要使用分支,如必须使用的话,优先选择常量的判定条件,其次选择 uniform 变量作为判定条件。
  2. 最糟糕的情况是使用 shader 内部计算的值作为判定条件,尽可能避免。
  3. 最终确定要使用分支,请确保两条分支不存在大量重复代码。大量重复代码会导致 shader 占用VGPR明显增多,减少 active warp 数量,最终导致性能下降。
  4. 尽管 step()`和 mix() 在某些情况下有助于优化性能,但它们可能会降低代码的可读性和维护性。这是一个权衡,需要在性能优化和代码清晰度之间找到平衡点。

参考资料:

vulkan uniform、推送常量、特化常量概念和用法
添加链接描述图形引擎实战:游戏GPU性能优化
深入GPU硬件架构及运行机制
GPU硬件架构概述
移动端GPU

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1958205.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于CentOS Stream 9平台安装MySQL Community Server 9.0.1 Innovation

1. 安装之前 1.1 查看系统版本 cat /etc/redhat-releaseCentOS Stream release 9 1.2 查看cpu架构 lscpu架构&#xff1a; x86_64 CPU 运行模式&#xff1a; 32-bit, 64-bit 2. 官网下载 https://dev.mysql.com/downloads/mysql/ 要多看看 官方9.0文档&#xff1a;https://d…

前端面试基础题(微信公众号:前端面试成长之路)

BFC、IFC、GFC、FFC CSS2.1中只有BFC和IFC, CSS3中才有GFC和FFC。 到底什么是BFC、IFC、GFC和FFC Whats FC&#xff1f; 一定不是KFC&#xff0c;FC的全称是&#xff1a;Formatting Contexts&#xff0c;是W3C CSS2.1规范中的一个概念。它是页面中的一块渲染区域&#xff0c;并…

【C++进阶学习】第九弹——哈希的原理与实现——开放寻址法的讲解

前言&#xff1a; 在前面&#xff0c;我们已经学习了很多存储机构&#xff0c;包括线性存储、树性存储等&#xff0c;并学习了多种拓展结构&#xff0c;效率也越来越高&#xff0c;但是是否有一种存储结构可以在大部分问题中都一次找到目标值呢&#xff1f;哈希可能能实现 目录…

npm国内淘宝镜像registry镜像过期

我们在使用npm的时候会遇到淘宝镜像安装过期的问题 首先了解 npm 淘宝镜像是一个 npm 注册表的镜像&#xff0c;用于加速 npm 包的下载。 一、如何设置&#xff1f; 如何设置淘宝镜像&#xff1f;淘宝镜像已经从 registry.npm.taobao.org 切换到了 registry.npmmirror.com n…

【书生大模型实战营(暑假场)】入门任务一 Linux+InternStudio 关卡

入门任务一 LinuxInternStudio 关卡 参考&#xff1a; 教程任务 1 闯关任务 1.1 基于 VScode 的 SSH 链接 感谢官方教程的清晰指引&#xff0c;基于VS code 实现 SSH 的链接并不困难&#xff0c;完成公钥配之后&#xff0c;可以实现快速一键链接&#xff0c;链接后效果如下…

搭建自动化 Web 页面性能检测系统 —— 部署篇

作为一个前端想去做全栈的项目时&#xff0c;可能第一个思路是 node vue/react。一开始可能会新建多个工程目录去实现&#xff0c;假设分别为 web 和 server&#xff0c;也许还有管理后台的代码 admin&#xff0c;那么就有了三个工程的代码。此时为了方便管理就需要在远程仓库…

JSON介绍及使用

目录 什么是JSON JSON在JavaScript中的使用 JSON的定义 JSON的访问 JSON的两个常用方法 JSON在Java中的使用 JavaBean和JSON的相互转换 List和JSON的相互转换 Map和JSON的相互转换 什么是JSON JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的…

No module named pip._internal.cli.main

conda 创建的虚拟化python2.7,里面没有pip报错&#xff1a;No module named pip._internal.cli.main 解决办法 使用 ensurepip 安装 pip python -m ensurepip --upgrade确认 pip 已正确安装 pip --version然后又遇到报错 此时我们只需要更新一下pip python -m pip install --up…

使用 Python 中的 ELSER 进行Serverless 语义搜索:探索夏季奥运会历史

作者&#xff1a;来自 Elastic Essodjolo Kahanam 本博客介绍如何使用语义搜索以自然语言表达形式从 Elasticsearch 索引中获取信息。我们将创建一个无服务器 Elasticsearch 项目&#xff0c;将之前的奥运会数据集加载到索引中&#xff0c;使用推理处理器和 ELSER 模型生成推理…

洛谷 P1883 【模板】三分 | 函数

原题 题目描述 给定 n 个二次函数 f1​(x),f2​(x),…,fn​(x)&#xff08;均形如 ax2bxc&#xff09;&#xff0c;设 &#x1d439;(&#x1d465;)F(x)max{f1​(x),f2​(x),...,fn​(x)}&#xff0c;求 &#x1d439;(&#x1d465;)F(x) 在区间[0,1000] 上的最小值。 输入…

PHP师生荣誉管理系统—计算机毕业设计源码10079

目 录 摘要 1 绪论 1.1 研究背景 1.2论文结构与章节安排 2 师生荣誉管理系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据增加流程 2.2.2 数据修改流程 2.2.3 数据删除流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 系统用例分析 2.…

Hive命令创建数据库和表(内置数据库)

【实验目的】 1) 了解hive操作命令 2) 熟悉hive数据库的操作 【实验原理】 配置完毕hive环境之后&#xff0c;通过hive指令进行创建数据库和表&#xff0c;这些信息被存放在metadata和hdfs上面&#xff0c;当执行操作之后&#xff0c;会在hdfs上有目录结构变化&#xff0c…

windows C/C++系列 64位汇编

Visual Studio 包括 32 位和 64 位托管版本的 MASM&#xff08;Microsoft 宏汇编程序&#xff09;&#xff0c;面向 x64 代码。 它的名称为 ml64.exe&#xff0c;是接受 x64 汇编程序语言的汇编程序。 当你在 Visual Studio 安装期间选择 C 工作负荷时&#xff0c;会安装 MASM …

【运维】远程控制与访问的协议(域,工作组,RDP,ARD,VNC,SSH,SCP)和工具(DDNS,跳板机,堡垒机)

【运维】远程控制与访问的协议&#xff08;域&#xff0c;工作组&#xff0c;RDP&#xff0c;ARD&#xff0c;VNC&#xff0c;SSH&#xff0c;SCP&#xff09;和工具&#xff08;DDNS&#xff0c;跳板机&#xff0c;堡垒机&#xff09; 文章目录 1、远程访问协议1.1 组织&#…

基于 SASL/SCRAM 让 Kafka 实现动态授权认证

一、说明 在大数据处理和分析中 Apache Kafka 已经成为了一个核心组件。然而在生产环境中部署 Kafka 时&#xff0c;安全性是一个必须要考虑的重要因素。SASL&#xff08;简单认证与安全层&#xff09;和 SCRAM&#xff08;基于密码的认证机制的盐化挑战响应认证机制&#xff…

傻瓜式PHP-Webshell免杀学习手册,零基础小白也能看懂

项目描述 一、PHP相关资料 PHP官方手册&#xff1a; https://www.php.net/manual/zh/ PHP函数参考&#xff1a; https://www.php.net/manual/zh/funcref.php 菜鸟教程&#xff1a; https://www.runoob.com/php/php-tutorial.html w3school&#xff1a; https://www.w3school…

网络流量分析>>pcapng文件快速分析有用价值解析

引言 在网络安全和流量管理中&#xff0c;解析网络协议数据包是了解网络行为和检测潜在威胁的关键步骤。本文介绍了如何使用Python解析和分析TCP、UDP和ICMP协议的数据包&#xff0c;并统计端口的访问次数。本文的示例代码展示了如何处理不同协议的数据包&#xff0c;提取关键…

网安零基础入门神书,全面介绍Web渗透核心攻击与防御方式!

Web安全是指Web服务程序的漏洞&#xff0c;通常涵盖Web漏洞、操作系统洞、数据库漏洞、中间件漏洞等。 “渗透测试”作为主动防御的一种关键手段&#xff0c;对评估网络系统安全防护及措施至关重要&#xff0c;因为只有发现问题才能及时终止并预防潜在的安全风险。 根据网络安…

前端面试宝典【vue篇】【3】

欢迎来到《前端面试宝典》,这里是你通往互联网大厂的专属通道,专为渴望在前端领域大放异彩的你量身定制。通过本专栏的学习,无论是一线大厂还是初创企业的面试,都能自信满满地展现你的实力。 核心特色: 独家实战案例:每一期专栏都将深入剖析真实的前端面试案例,从基础知…

phpenv安装redis扩展

1、下载dll文件 https://pecl.php.net/package/redis 我的是php8.1, 安装最新版的 DLL文件 &#xff12;、将dll文件放到php安装目录的ext目录下 3、在php.ini中增加配置后重启服务 [Redis] extension php_redis.dll