当前位置: 首页 > news >正文

OpengES中 GLSL优化要点

本文整理一些日常积累的可以优化的方向

一.延迟vector计算

在进行float与vector计算的时候,可以先确定float再计算,不要多个float一起计算
如:

  highp float f0,f1;highp vec4 v0,v1;v0 = (v1 * f0) * f1;

优化为

  highp float f0,f1;highp vec4 v0,v1;V0 = v1 * (f0 * f1)

二.避免分支语句(if和个别for语句)

以OpenGL通常处理的图像来说,OpenGL的shader在运算的时候,会产生成千上万个线程来对不同的点位区域进行计算,每个线程都使用同一份shader代码、但是处理的数据不同。为了大幅度提高计算速度,OpenGL利用了GPU,而GPU的基本调度单位叫做wavefront(不同平台理念相同、叫法不同,NVIDIA平台叫warp,AMD平台叫wavefront等, 下面统称为wavefront)。wavefront是一组线程的组合,既然称之为调度的基本单位,自然是GPU会同时处理属于同一个wavefront的所有线程,因为他们的计算指令(shader)从第一行到最后一行是完全相同的,只是数据不同而已。GPU正是这样通过single instruction multiple thread(SIMT)的方式来进行提速的。这有点类似于CPU中的SIMD加速,只不过CPU中一次SIMD操作只针对一组数据、需要人为编码控制,而GPU的SIMT是从始至终的用相同指令计算所有的线程数据。这样并行度极高,从而大幅提升了性能。

但是一旦引入if/for产生分支,wavefront结构就被完全破坏掉了,会产生diverged wavefront。例如原本4个线程组成一个wavefront一直同步计算,突然遇到if语句,3个线程if判断为true,进入A分支;另一个线程if判断为false,进入B分支,此时这4个线程接下来的指令不再相同,原来的这个线程组wavefront就无法同步计算、被迫分开,即为diverged wavefront。这时候,GPU只能分开执行这两个新产生的wavefront。由于GPU计算资源也是一定的,新产生的两个wavefront可能需要排队等待来顺序执行(原来是并行执行),尤其是wavefront大批量diverged的时候;然后新分割出来的wavefront如果要移动到其他GPU计算单元上还需要进行数据复制转移,也是很耗时的行为。这些都严重破坏了并行度,从而导致性能下降。因此,建议最好少使用产生分支的if语句;for语句有时候也会产生分支,也需要注意。

优化策略

  1. 用step方法或者其他的方法替换掉分支语句
    step是阶跃函数,输入两个参数edge,x。如果edge > x返回0,否则返回1.

    vec3 a;
    if (b > 1)
    {a = 1;
    }
    else
    {a = 0.5;
    }
    

    替换为

    vec3 a;
    float temp = step(b, 1.0);
    a =  1.0 - temp * 0.5;
    
  2. 如果不可避免进行分支操作,要先选择可以被优化的分支
    编译器有时可以对分支进行一定的优化。If判断条件一般包含三种数据:

    (1)静态分支:If判断语句仅仅包含常数;

    (2)uniform数据分支:If判断语句仅仅包含常数或uniform参数;

    (3)动态分支:其他情况,If判断语句中有动态变化的数据。

    按道理来说,静态数据和uniform数据不会变化,编译器应该可以判断并进行编译优化,但是对于Android开发来说,硬件千差万别,目前据我了解,对于OpenGL ES 2.0,基本上大都只能优化静态分支;对于OpenGL ES 3.0,通常可以优化uniform数据分支,部分机型可能可以优化动态分支。

    所以,写分支的时候注意分支的类型,并且如果升级到OpenGL ES 3.0,就基本可以使用uniform数据分支而没有明显的性能损失了。

    同理,如果for循环的此时是一个整数、即常量,那么也不会产生分支;只有当for循环的次数也是随着点位的不同动态变化的时候才会产生分支。

  3. 相同区块情况可以使用分支
    一般来说,相邻的点位区域的线程会组合在同一个wavefront中,如果一个分支与位置相关,例如图像上半部分都是黑色,下半部分是彩色;而If判断条件是颜色是否为黑色,那么大部分情况下同一个wavefront的线程都会在if判断后走同一个分支,这样wavefront就不会diverge。或者判断条件是和位置有关的,那么大概率也不会diverge。只要不产生diverge就不会对性能有很大影响。

  4. 全量代码,但保证某些分支不起作用
    比如如下:

    if (a == 0) {result = funcA();
    } else {result = funcB();
    }
    

    可以替换为:

    result = funcA();
    result = funcB();
    

    计算全部的函数,这样就避免了分支, 很多情况下,全量执行所有分支的代码比使用If判断还要快,这个可以通过实际测试比较来进行选择。

三. 计算尽量提前到顶点着色器

比如在计算一些面的法向量的时候,可以在Vertex Shader中计算完成,然后传递给
Fragment Shader,减少计算量。

四.使用更少的颜色分量参与计算

五.降低数据的精度

比如,从Vertex Shader传递到Fragment Shader的纹理坐标精度从highp改成mediump也会降低一些消耗。

参考

https://blog.csdn.net/qq_30070433/article/details/87392605
https://cloud.tencent.com/developer/beta/article/1370101
https://blog.csdn.net/ShareUs/article/details/94922200

相关文章:

OpengES中 GLSL优化要点

本文整理一些日常积累的可以优化的方向 一.延迟vector计算 在进行float与vector计算的时候,可以先确定float再计算,不要多个float一起计算 如: highp float f0,f1;highp vec4 v0,v1;v0 (v1 * f0) * f1;优化为 highp float f0,f1;highp vec…...

项目集角色定义

一、项目集经理的角色 项目集经理是由执行组织授权、领导团队实现项目集目标的人员。项目集经理对项目集的领导、 实施和绩效负责,并负责组建一支能够实现项目集目标和预期项目集效益的项目集团队。项目集经 理的角色与项目经理的角色不同。二者之间的差异是基于项…...

Unreal Engine11:触发器和计时器的使用

写在前面 主要是介绍一下触发器和计时器的使用; 一、在Actor中使用触发器 1. 新建一个C类 创建的C类也是放在Source文件夹中的Public和Private文件夹中;选择Actor作为继承的父类;头文件包括一个触发器和两个静态网格,它们共同…...

Qt之信号槽原理

Qt之信号槽原理 一.概述 所谓信号槽,实际就是观察者模式。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这…...

【MySqL】 表的创建,查看,删除

目录 一.使用Cmd命令执行操作 1.使用( mysql -uroot -p)命令进入数据库 2.创建表之前先要使用数据库 3.创建表之前要先确定表的名称,列名,以及每一列的数据类型及属性 4.创建表 注意: 5.查看所有已创建的表 6.查看单表 …...

Python 字典修改对应的键值

将 key ‘1’ 的值 ‘1’, ‘3’, ‘5’ 字符,修改为 ‘2’, ‘4’, ‘5’ 。 【学习的细节是欢悦的历程】 Python 官网:https://www.python.org/ Free:大咖免费“圣经”教程《 python 完全自学教程》,不仅仅是基础那么简单………...

【JFace】ComboViewer 设置了默认值,但没有效果

问题 在数据回显时,明明在代码中通过comboViewer.setSelection设置了默认值,但没有生效(回显),是怎么回事呢 ? 分析 如果comboViewer.setSelection(new StructuredSelection(items[1]))不起作用&#xf…...

基于Redis的Stream结构作为消息队列,实现异步秒杀下单

文章目录 1 认识消息队列2 基于List实现消息队列3 基于PubSub的消息队列4 基于Stream的消息队列5 基于Stream的消息队列-消费者组6 基于Redis的Stream结构作为消息队列,实现异步秒杀下单 1 认识消息队列 什么是消息队列:字面意思就是存放消息的队列。最…...

ePWM模块-时基模块(2)

ePWM模块(2) 时基模块的使用 TBPRD:周期寄存器 (设置的时钟周期存入此,可通过阴影寄存器缓冲后写入,也可通过活动寄存器立即写入) TBCTR:时基计数变值寄存器 (时基当前所计数的值存入,用于和所设定周期值比较) TBPHS:时基相位寄存器 TBSTS:时基状态寄存器 …...

让GPT对话写小说

## 来自你的消息: 写个小说 ## 来自ChatAI的消息: 很好,我可以为您编写一个小故事。以下是一个短小精干的故事: 《夜行者》 夜,是个寂静而神秘的时间,很多人都选择睡眠。但在这个城市,有一群人——夜行者,他…...

Docker 应用部署-MySQL

一、安装MySQL 1搜索mysql镜像 docker search mysql 2拉取mysql镜像 docker pull mysql:8.0.20 3创建容器 通过下面的命令,创建容器并设置端口映射、目录映射 #在用户名目录下创建mysql目录用于存储mysql数据信息 mkdir /home/mysql cd /home/mysql #创建docker容…...

电容笔哪个厂家的产品比较好?苹果平板的电容笔推荐

从目前来说,这个苹果的正版电容笔,售价真的是太贵了,一支就要接近上千元。事实上,对于那些没有很多预算的人来说,平替电容笔是一个很好的选择。一支苹果电容笔,价格是四支平替电容笔的四倍,但平…...

今年的面试难度有点大....

大家好,最近有不少小伙伴在后台留言,又得准备面试了,不知道从何下手! 不论是跳槽涨薪,还是学习提升!先给自己定一个小目标,然后再朝着目标去努力就完事儿了! 为了帮大家节约时间&a…...

【PWN · ret2libc】ret2libc2

ret2libc1的略微进阶——存在systemplt但是不存在“/bin/sh”怎么办? 目录 前言 python3 ELF 查看文件信息 strings 查看寻找"/bin/sh" IDA反汇编分析 思路及实现 老规矩,偏移量 offset EXP编写 总结 前言 经过ret2libc1的洗礼&a…...

深度学习01-tensorflow开发环境搭建

文章目录 简介运行硬件cuda和cuddntensorflow安装。tensorflow版本安装Anaconda创建python环境安装tensorflow-gpupycharm配置配置conda环境配置juypternotebook 安装cuda安装cudnn安装blas 云服务器运行云服务器选择pycharm配置代码自动同步远程interpreter 简介 TensorFlow是…...

linux相关操作

1 系统调用 通过strace直接看程序运行过程中的系统调用情况 其中每一行为一个systemcall ,调用write系统调用将内容最终输出。 无论什么编程语言都必须通过系统调用向内核发起请求。 sar查看进程分别在用户模式和内核模式下的运行时间占比情况, ALL显…...

PMP项目管理-[第十章]沟通管理

沟通管理知识体系: 规划沟通管理: 10.1 沟通维度划分 10.2 核心概念 定义:通过沟通活动(如会议和演讲),或以工件的方式(如电子邮件、社交媒体、项目报告或项目文档)等各种可能的方式来发送或接受消息 在项目沟通中,需要…...

13个UI设计软件,一次满足你的UI设计需求

UI设计师的角色是当今互联网时代非常重要的一部分。许多计算机和移动软件都需要UI设计师的参与,这个过程复杂而乏味。这里将与您分享13个UI设计软件,希望帮助您正确选择UI设计软件,节省工作量,创建更多优秀的UI设计作品。 1.即时…...

sentinel介绍

介绍 官网地址 Sentinel 和 Hystrix 的原则是一致的: 当调用链路中某个资源出现不稳定,例如,表现为 timeout,异常比例升高的时候,则对这个资源的调用进行限制,并让请求快速失败,避免影响到其它的资源&…...

手把手教你怎么搭建自己的ChatGPT和Midjourney绘图(含源码)

AI程序采用NUXT3LARAVEL9开发(目前版本V1.1.7) 授权方式:三个顶级域名两次更换 1.AI智能对话-对接官方和官方反代(markdown输出)PS:采用百度与自用库检测文字 2.AI绘图-根据关键词绘图-增加dreamStudio绘画-增加mid…...

【JavaEE】-- HTTP

1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

如何为服务器生成TLS证书

TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

如何在网页里填写 PDF 表格?

有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据&#xff…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...