精华内容
下载资源
问答
  • 可打印版本附pdf下载链接 先给一张侧脸(关键1): 再给一张正脸(关键2): 然后仅仅根据这两张图片,AI处理了一下,便能生成整个运动过程: 而且不只是简单的那种,连在运动过程中的眨眼动作也“照顾”得很...

    点上方计算机视觉联盟获取更多干货

    仅作学术分享,不代表本公众号立场,侵权联系删除

    转载于:量子位

    AI博士笔记系列推荐

    周志华《机器学习》手推笔记正式开源!可打印版本附pdf下载链接

    先给一张侧脸(关键帧1):

    再给一张正脸(关键帧2):

    然后仅仅根据这两张图片,AI处理了一下,便能生成整个运动过程

    而且不只是简单的那种,连在运动过程中的眨眼动作也“照顾”得很到位。

    效果一出,便在Reddit上引发了不少热议:

    仅需2个关键帧,如何实现完整运动?

    不需要冗长的训练过程。

    不需要大量的训练数据集。

    这是论文作者对本次工作提出的两大亮点。

    具体而言,这项工作就是基于关键帧将视频风格化。

    先输入一个视频序列 I ,它由N个帧组织,每一帧都有一个掩膜Mi来划分感兴趣的区域。

    与此前方法不同的是,这种风格迁移是以随机顺序进行的,不需要等待顺序靠前的帧先完成风格化,也不需要对来自不同关键帧的风格化内容进行显式合并。

    也就是说,该方法实际上是一种翻译过滤器,可以快速从几个异构的手绘示例 Sk 中学习风格,并将其“翻译”给视频序列 I 中的任何一帧。

    这个图像转换框架基于 U-net 实现。并且,研究人员采用基于图像块 (patch-based)的训练方式和抑制视频闪烁的解决方案,解决了少样本训练和时间一致性的问题。

    而为了避免过拟合,研究人员采用了基于图像块的训练策略。

    从原始关键帧(Ik)中随机抽取一组图像块(a),在网络中生成它们的风格化对应块(b)。

    然后,计算这些风格化对应块(b)相对于从风格化关键帧(Sk)中取样对应图像块的损失,并对误差进行反向传播。

    这样的训练方案不限于任何特定的损失函数。本项研究中,采用的是L1损失、对抗性损失和VGG损失的组合。

    另一个问题便是超参数的优化

    这是因为不当的超参数可能会导致推理质量低下。

    研究人员使用网格搜索法,对超参数的4维空间进行采样:Wp——训练图像块的大小;Nb——一个batch中块的数量;α——学习率;Nr——ResNet块的数量。

    对于每一个超参数设置:

    (1)执行给定时间训练;

    (2)对不可见帧进行推理;

    (3)计算推理出的帧(O4)和真实值(GT4)之间的损失。

    而目标就是将这个损失最小化。

    团队介绍

    这项研究一作为Ondřej Texler,布拉格捷克理工大学计算机图形与交互系的博士生。

    而除了此次的工作之外,先前他和团队也曾做过许多有意思的工作。

    例如一边画着手绘画,一边让它动起来。

    再例如给一张卡通图片,便可让视频中的你顶着这张图“声情并茂”。

    想了解更多有趣的研究,可戳下方链接????。

    参考链接:

    [1]https://www.reddit.com/r/MachineLearning/comments/n3b1m6/r_fewshot_patchbased_training_siggraph_2020_dr/
    [2]https://ondrejtexler.github.io/patch-based_training/index.html

    -------------------

    END

    --------------------

    我是王博Kings,985AI博士,华为云专家、CSDN博客专家(人工智能领域优质作者)。单个AI开源项目现在已经获得了2100+标星。现在在做AI相关内容,欢迎一起交流学习、生活各方面的问题,一起加油进步!

    我们微信交流群涵盖以下方向(但并不局限于以下内容):人工智能,计算机视觉,自然语言处理,目标检测,语义分割,自动驾驶,GAN,强化学习,SLAM,人脸检测,最新算法,最新论文,OpenCV,TensorFlow,PyTorch,开源框架,学习方法...

    这是我的私人微信,位置有限,一起进步!

    王博的公众号,欢迎关注,干货多多

    王博Kings的系列手推笔记(附高清PDF下载):

    博士笔记 | 周志华《机器学习》手推笔记第一章思维导图

    博士笔记 | 周志华《机器学习》手推笔记第二章“模型评估与选择”

    博士笔记 | 周志华《机器学习》手推笔记第三章“线性模型”

    博士笔记 | 周志华《机器学习》手推笔记第四章“决策树”

    博士笔记 | 周志华《机器学习》手推笔记第五章“神经网络”

    博士笔记 | 周志华《机器学习》手推笔记第六章支持向量机(上)

    博士笔记 | 周志华《机器学习》手推笔记第六章支持向量机(下)

    博士笔记 | 周志华《机器学习》手推笔记第七章贝叶斯分类(上)

    博士笔记 | 周志华《机器学习》手推笔记第七章贝叶斯分类(下)

    博士笔记 | 周志华《机器学习》手推笔记第八章集成学习(上)

    博士笔记 | 周志华《机器学习》手推笔记第八章集成学习(下)

    博士笔记 | 周志华《机器学习》手推笔记第九章聚类

    博士笔记 | 周志华《机器学习》手推笔记第十章降维与度量学习

    博士笔记 | 周志华《机器学习》手推笔记第十一章稀疏学习

    博士笔记 | 周志华《机器学习》手推笔记第十二章计算学习理论

    博士笔记 | 周志华《机器学习》手推笔记第十三章半监督学习

    博士笔记 | 周志华《机器学习》手推笔记第十四章概率图模型

    点分享

    点收藏

    点点赞

    点在看

    展开全文
  • 控制台命令 r.screenpercentage 0~100 0是百分之百 如果改了这个 游戏运行超级流畅说明瓶颈在GPU上 stat fps 显示帧率(Frame Per Second)...stat game 查看每一有多少tick操作 stat memory 查看内存使用情况 r.maxfp

    控制台命令

    • r.screenpercentage 0~100 0是百分之百 如果改了这个 游戏运行超级流畅说明瓶颈在GPU上
    • stat fps 显示帧率(Frame Per Second)(或者Crlt+Shift+H 显示帧率)
    • stat unit 把Frame拆分 其中最接近 Frame的就是瓶颈,Game可以粗暴理解为 CPU方面的
    • stat rhi 查看draw call和三角面
    • stat game 查看每一帧有多少tick操作
    • stat memory 查看内存使用情况
    • r.maxfps 80 更改帧数限制
    • show static/skeleton mesh 显示隐藏静态/骨架网格体
    • show translucency 显隐半透明材质
    • stat sceneRendering (类似于rhi)场景渲染查看、检查CPU使用率 主要看 Draw calls
    • r.shadowquality 0~5 阴影质量 0是无
    • freezerendering 冻结渲染,即冻结此刻摄像机所在的位置 只显示场景中已经渲染的对象,此刻 绘制进程是停止状态,不会再绘制,可以查看锥形剔除的效果
    • Stat initviews 提供有关遮挡的概览,
      下方Counters里面 Processed primitives(进行中的图元)——目前渲染的对象数量。
      Frustum culled primitives(椎体剔除的图元)——目前被椎体剔除的对象数量
      Statically occluded primitives(静态遮挡图元)——被与计算可见性单元格剔除的对象数。

    其他相关知识

    • Ctrl + Shift + ,GPU可视化工具
      此工具可以看到GPU在引擎各个工作上面的性能消耗
      如果是Postprocess消耗过高,可以删除一些光源,或者改用静态光源子类的
    • Draw call降低方式
      draw call 引擎代码发送的用来绘制一组多边形的指令是CPU发出的
      影响因素:多边形数量、材质复杂性
      解决办法:减少对象数量、合并对象、移除外部材质通道、减少动态投射的阴影数量
    • 性能消耗查看——视图模式
      Light Complexity:看光照对GPU的消耗;用渐变的颜色显示场景,绿->红->白等颜色表示性能消 耗递增,优化方法:降低光照重叠部分,静态模型用静态光。
      Shader Complexity:看着色器指示的数量,跟材质有关的,比如透明材质会消耗很大 如果透明材 质重叠则更大。优化方法:换材质
      Quad Overdraw:模型面数可视化。优化方式:LOD细节等级、剔除距离体积
    • Jacketing功能
      通常导入的建筑或者工业模型会有一些用户永远看不到的面数又很大的部分,这时候需要用jacketing功能来剔除对象和不需要的多边形。注意这个操作是不可逆的,所以通常以防万一需要备份原来的模型。
      启用“Polygon Editing”插件,在视口中选择要修改的对象或者对象组,右击选择jacketing,弹出框内,Action level 选择level或者mesh
      level适合用于一个对象含有许多零件,而这些零件在外部任何角度都看不见,剔除构件。
      mesh从单个三角形的层面出发,剔除某个模型从外部任何角度都看不见的三角面,剔除三角面。
    • 实例化静态网格体 Instanced Static Meshes
      多个网格体只有一次Draw call

    项目设置

    • Target Hardware
      设置目标硬件是Table/Mobile,选移动平台会禁用很多设置;
      还可以设置项目注重画面质量还是运行速度。

    • General Setting -> Framerate(帧率)
      Fixed Frame Rate(使用固定帧率)
      Smooth Frame Rate(范围内平滑帧率)

    • Rendering -> Culling
      确保Occlusion Culling(遮蔽剔除)是开启的。(默认开启)

    • Rendering -> Reflections
      调整分辨率或者反射步骤来节省GPU绘制时间,数值2的次方

    • Rendering -> Default Settings
      这里的设置是”后期处理”的内容,是全局性的,会被后期处理体和摄像机Actor中的设置覆盖

    • Rendering -> Default Settings -> Ray Tracing
      实时光线追踪超级消耗性能,如果不需要实时光线追踪来实现真实反射效果、全局照明等效果 请禁用。并且在VR和Mobile应用中无效。

    LOD 细节等级设置

    • LOD:Level of Detail,LOD是同一3D模型的不同版本具有不同程度的细节,根据观看者离物体的距离决定的。

    • 设置LOD:打开模型编辑器,左上角可以看到Triangles的数量,在LOD Picker下可以选择是自定义或者自动生成LOD“Custom”“Auto”.其中LOD Auto:下面有LOD Settings,可以在LOD Group里面选择削减方式,如SmallProp。

    • 批量设置LOD:内容浏览器中选中所有的模型,右键->Asset Actions-> Bulk Edit via Property Matrix
      通过属性矩阵进行批量编辑。这个窗口中可以同时更改多个对象的设置

    • 设置LOD后,在编辑视口->视图模式-> Level of Detail Coloration -> Mesh LOD Coloration 可以用颜色显示模型在什么时候显示什么等级的细节

    使用Data Smith插件在导入前进行LOD优化

    • 首先用DataSmith从3D建模软件把模型导出成udatasmith格式文件
    • UE4中右键创建 DataPrep Asset,这里面可以在模型导入编辑器之前 对其进行预览和处理;打开后 Imputs+,选择udatasmith文件,然后点击左上角 import。
    • 在大型建筑群项目用这个方法会非常好,首先要设定“选择标准”,在Select By下找到Triangle Count即用三角面数作为选择条件,拖入右边窗口。选择高于500面,然后在Operations下拖出“set LOD Group”,点击Execute,会自动处理,处理完毕后 点击Commit提交

    渲染方式

    • 延迟渲染:UE4默认渲染模式,用于大型游戏 重影是缺点
    • 正向渲染:VR AR等小项目多用这个,抗锯齿更好
    • 延迟渲染有个GBuffer缓冲区,存放每一帧要用到的图片信息,比如有粗糙度的图、底色图、金属感的图、像素位置图等等
    • UE4以draw call 为单位进行渲染 主要FPS影响在于draw call数量, 如场景中对象全部是复制品,面数极高,但是帧数可能会高于面数低但全为不同对象的情况

    距离剔除

    • 每个对象细节面板rendering>lod下面的最大绘制距离 可以控制远处对象不渲染(单个物体进行设置),但是如果用CullDistanceVolume 可以对盒子内所有的物体 同时设置渲染距离

    椎体剔除

    • 这是图形学基本概念,只渲染视椎体内部的对象,看到一个像素也会渲染整个对象,以对象为单位

    预计算可见性体积PreconputedVisibilityVolume

    • 要先添加一个与计算可见性体积盒子,盒子内的对象都会被预计算可见性的单元格填充,这些单元格要通过光照构建才能生成,之后必须在视口 显示>可视化>设置预计算可见性单元格勾选。
    • 这个东西每个单元格都包含一个表格,记录了当前位置可以看见的对象,当摄像机进入任何一个单元格,都会访问表格

    抖动过渡Dithered LOD Transition

    • UE4会自带某个临界距离,远则模型粗糙,近则模型细致,但是这个变化是特别突兀的。
      在母类材质中,搜索Dithered LOD Transition勾选,可以平滑过渡这一变

    检查内存使用率

    • 影响内存的因素主要是场景中的纹理Texture
      window > statistics > 下拉选择Texture Stats,查看Fully Loaded Memory即加载全部纹理需要的内存容量,点击这个选项卡更改为从高到低排序,可以查看哪个纹理占用的内存最大。在内容浏览器中找到它,点开后更改最大纹理尺寸 Maximum Texture Size 为2的整数次方,再去查看就可以看到总的加载内存消耗变低了。
    • 控制台:Streaming PollSize +整数MB 选择用多少MB内存来流送纹理
    展开全文
  • FuncAnimation是matplotlib生成动画的常用类,它的工作原理就是按照一定时间间隔不断调用参数func对应的函数生成动画。 FuncAnimation的继承关系如下: matplotlib.animation.Animation→matplotlib.animation....

    当前有效matplotlib版本为:3.4.1

    概述

    逐帧动画(Frame By Frame)是一种常见的动画形式,通过将不同的静止图像以一定时间间隔连续播放,因人类视觉暂停现象而获得动画的效果。

    FuncAnimationmatplotlib生成逐帧动画的常用类,它的工作原理就是按照一定时间间隔不断调用参数func对应的函数生成动画。

    FuncAnimation的继承关系如下:
    matplotlib.animation.Animation→matplotlib.animation.TimedAnimation→matplotlib.animation.FuncAnimation

    FuncAnimation类的签名为:class matplotlib.animation.FuncAnimation(fig, func, frames=None, init_func=None, fargs=None, save_count=None, *, cache_frame_data=True, **kwargs)

    构造函数参数如下:

    • fig :承载动画的图形对象。 matplotlib.figure.Figure对象。必备参数。
    • func : 每一帧都需要调用的函数。可调用对象。必备参数。
      func 的签名如下为 def func(frame, *fargs) -> iterable_of_artists。第一个参数为frames参数传递过来的一个元素,剩余位置参数由fargs参数提供。
      如果 blit == Truefunc必须返回一个包含所有已创建或修改的可视化对象(artist)的可迭代对象。如果 blit == False ,返回值将被忽略。
    • frames :用于向func生成的每一帧传递一个值。可迭代对象,整数,生成器或None,可选参数。
      • 如果值为可迭代对象,直接使用可迭代对象。如果可迭代对象长度固定,将会覆盖save_count参数。
      • 如果值为整数,相当于传递range(frames)
      • 如果值为生成器,生成器的签名要求为def gen_function() -> obj
      • 如果值为None,相当于传递 itertools.count
    • init_func : 用于初始化帧的函数,在生成第1帧之前,会调用一次该函数。可调用对象。可选参数。如果不提供改参数, 将使用frames参数中的第一个元素的绘制结果。该参数的签名要求为def init_func() -> iterable_of_artists,除了参数,其余要求与func 参数类似。
    • fargs : 传递给func的附加参数。元组或None。可选参数。
    • save_count : 用于缓存frames值的数量,该参数只用于frames值数量不能推断出的情况。整数。默认值为100
    • interval:帧之间的间隔毫秒数。整数。默认值为200
    • repeat_delay:当repeatTrue时生效。即动画重复执行的间隔毫秒数。当整数。默认值为0
    • repeat :当帧序列执行一次之后是否重复执行。布尔值。默认值为True
    • blit: 是否采用按叠放次序(zorder)优化绘图模式。布尔值。默认值为False
    • cache_frame_data :每帧数据是否被缓存。布尔值。默认值为True

    FuncAnimation类继承了matplotlib.animation.Animation类的pauseresume方法,可实现动画的暂停和继续功能。

    案例1:动态绘制sin曲线

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.animation as animation
    
    
    fig, ax = plt.subplots()
    # 构造空线条
    line, = ax.plot([], [])
    # 构造线条数据结构
    xdata, ydata = [], []
    # 设置坐标轴刻度范围
    ax.set_ylim(-1.1, 1.1)
    ax.set_xlim(0, 50)
    
    # 动画循环一次后进行初始化,清空数据
    def init():
        del xdata[:]
        del ydata[:]
        line.set_data(xdata, ydata)
        return line,
    
    # 控制每帧画面如何绘制
    def update(x):
        y = np.sin(x)
        xdata.append(x)
        ydata.append(y)
        xmin, xmax = ax.get_xlim()
        line.set_data(xdata, ydata)
        fig.canvas.draw()
        return line,
    
    ani = animation.FuncAnimation(fig, update, 50, interval=10, init_func=init)
    
    plt.show()
    

    案例2:点击鼠标左键暂停/继续动画

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.animation as animation
    
    
    fig, ax = plt.subplots()
    # 构造空线条
    line, = ax.plot([], [])
    # 构造线条数据
    n = 50
    x = np.arange(n)
    y = np.sin(x)
    # 设置坐标轴刻度范围
    ax.set_ylim(-1.1, 1.1)
    ax.set_xlim(0, n)
    
    
    # 控制每帧画面如何绘制
    def update(i):
        line.set_data(x[:i], y[:i])
        return line,
    
    ani = animation.FuncAnimation(fig, update, n, interval=10,)
    
    # 事件处理
    paused = False
    
    def toggle_pause(event):
        global paused
        if paused:
            ani.resume()
        else:
            ani.pause()
        paused = not paused
    
    fig.canvas.mpl_connect('button_press_event', toggle_pause)
    
    plt.show()
    
    
    展开全文
  • 01 工具链/应用程序优化 导读:嵌入式Linux在应用中往往希望系统能在尽量短的时间内启动,以提高用户体验。而且在有的应用场合,对启动时间具有严格的时间要求,尤其在工业或者医疗器械应用领域。此时如何加快Linux...

    01 工具链/应用程序优化

    导读:嵌入式Linux在应用中往往希望系统能在尽量短的时间内启动,以提高用户体验。而且在有的应用场合,对启动时间具有严格的时间要求,尤其在工业或者医疗器械应用领域。此时如何加快Linux的启动,将成为一个挑战,对于大多数应用开发人员而言,由于Linux系统的复杂性,对于如何提高启动速度,往往无从下手。那么阅读完本文,将获得清晰完整的解决思路。

    注:本文转载自微信公众号:嵌入式ARM。

    1.降低启动时间的一般思路

    在准备降低系统的启动时间时,思路上应建立以下的切入点:

    • 最快的代码是未执行的代码。

    • 引导操作本质上的很大一部分工作实际上是将代码和数据从存储设备加载到RAM。如所需加载内容越少则意味着加载操作越快。 

    • 如果根文件系统越大,则安装时间可能会越长。

    • 因此,即使未执行的代码也会延长启动时间。

    • 另外在硬件方案设计时尽量选择读写速度快的存储介质。例如,从SD卡启动实际上比从NAND FLASH启动快。

       

    2.启动时间测量方法

    要降低系统的启动时间,则首先需要选择一个可靠的启动时间的测量方法:

    • 在Linux代码中加入对某一个GPIO脚的逻辑电平控制,利用示波器测量GPIO状态。后面将介绍如何在代码中加入对GPIO的控制。

    • 监控串口控制台报文以测量时间,可以使用grabserial。

      参见https://elinux.org/Grabserial

       

    3. 工具链优化

    3.1 从工具链入手

    选择使用合适的工具链,应是第一个入手点,因为所有的运行加载固件都是由工具链编译而成。如果尚未进行其他优化,则更改工具链的好处将更加明显,并且更容易度量。

    您可以在工具链中进行以下更改,这可能会影响启动时间,性能和大小:

    • 编译器版本:gcc和binutils的版本,最新版本往往可以具有更好的优化功能。

    • C库:glibc,uClibc,musl。使用uClibc和musl库编译的根文件系统更小

    • 指令集变量:ARM或Thumb2,是否支持硬浮点。

    • 可能会影响代码性能和代码大小(Thumb2编码与ARM相同的指令,但以更紧凑的方式,至少会显着减小大小)。

       

    C库在创建工具链时进行了硬编码,可供选择的C库:

    • glibc:最标准且功能最全。http://www.gnu.org/software/libc/

    • uClibc:更小且可配置。已经存在约20年了。http://uclibc-ng.org/

    • musl:uClibc替代品,虽比较新但很成熟。http://www.musl-libc.org/

     

    可以对glibc/uclibc-ng /musl进行对比测试:

    1.静态编译hello.c程序并比较大小

    • 使用gcc 6.3, armel, musl 1.1.16:           7300   字节

    • 使用gcc 6.3, armel, uclibc-ng 1.0.22 :  67204  字节

    • 使用gcc 6.2, armel, glibc:                    492792 字节

    2. 静态编译BusyBox 1.26.2并比较大小

    • 使用gcc 6.3, armel, musl 1.1.16:         183348   字节

    • 使用gcc 6.3, armel, uclibc-ng 1.0.22 : 210620   字节

    • 使用gcc 6.2, armel, glibc:                    755088   字节

     

    3.2 指令集选择

    编译rootfs进行测试对比:

    • 用gcc 7.4编译,生成ARM代码:

           根文件系统总大小:3.79 MB

    • 用gcc 7.4编译,生成Thumb2代码:

      根文件系统总大小:3.10 MB(-18%)

      性能方面:Thumb2的性能明显改善(大约少于5%,但是从一次运行到另一次运行,测量的执行时间略有变化)。

       

    4. 应用软件优化

    4.1 测量strace

    strace允许跟踪应用程序及其子级进行的所有系统调用。对于开发非常有用:

    • 了解如何在用户空间上花费时间

    • 例如,轻松查找打开尝试(open()),文件访问(read() /write() )和内存分配(mmap2() )。无需访问源代码即可完成!

    • 寻找耗时最长的开销应用

    • 查找在应用程序和脚本中完成的不必要的工作。例如:多次打开同一文件,或尝试打开不存在的文件。

    • 局限性:您无法跟踪init进程!

     

    关于strace 参见

    http://sourceforge.net/projects/strace/:

    • 在所有GNU / Linux系统上可用,可以由您的交叉编译工具链生成器构建。

    • 更简单的办法:直接拷贝一个现成的静态二进制文件。 参见

    https://github.com/bootlin/static-binaries/tree/master/strace

    • 可以查看进程的操作情况:

      1. 访问文件,分配内存...

      2. 通常足以发现简单的错误。

    • 用法:

      1.strace <命令>(开始一个新进程)

      2.strace -p <pid>(跟踪现有进程)strace -c <command>(统计进程的系统开销时间)

     

    如查看cat操作:

    图片

     

    又如统计进程的调用时间:

    图片

     

    4.2 Linux上的性能监测工具oprofile

    Oprofile是linux上的性能监测工具:

    • 具有两种工作方式:legacy模式和perf_events模式

    • legacy模式:

      1.精度低,请使用内核驱动程序进行配置

      2.使用CONFIG_OPROFILE进行编译配置

      3.用户空间工具:opcontrol和oprofiled

    • perf_events模式:

      1.使用硬件性能计数器

      2.使用CONFIG_PERF_EVENTS和CONFIG_HW_PERF_EVENTS编译配置

      3.用户空间工具:operf

     

    其使用方法:

    • legacy 模式:

      opcontrol --vmlinux=/path/to/vmlinux # optional step

      opcontrol --start

      /my/command

      opcontrol --stop

    • perf_events 模式

      operf --vmlinux=/path/to/vmlinux /my/command

    • 利用opreport获取结果

     

    例如:

    图片

    4.3 perf工具

    Perf 是内置于Linux 内核源码树中的性能剖析(profiling)工具。它基于事件采样原理,以性能事件为基础,支持针对处理器相关性能指标与操作系统相关性能指标的性能剖析。可用于性能瓶颈的查找与热点代码的定位。linux2.6及后续版本都自带该工具,几乎能够处理所有与性能相关的事件

    • 使用硬件性能计数器

    • 使用CONFIG_PERF_EVENTS和CONFIG_HW_PERF_EVENTS进行配置

    • 用户空间工具:性能。它是内核源代码的一部分,因此始终与您的内核同步。

    • 用法:perf record /my/command

    • 通过以下方式获得结果:perf report

     

    例如:

    图片

     

    4.4 连接器优化

    启动时使用的应用程序组代码:

    • 查找启动期间调用的功能,例如使用

      -finstrument-functions gcc选项。

    • 创建一个自定义的链接描述文件,以按调用顺序重新排列这些函数。可以通过将每个函数放在各自的部分中来实现:

      -ffunction-sections gcc选项。

    • 特别对于具有较大MTD读取块的闪存存储特别有用。因为读取整个读取块后,极有可能读取不必要的数据。

      详细信息:http://blogs.linux.ie/caolan/2007/04/24/controlling-symbol-ordering/

    • 通过如下方法,可以找到有望被优化的地方:

      1.启动一次应用程序并测量其启动时间。

      2.再次启动应用程序并测量其启动时间。由于它的代码应仍在Linux文件缓存中,故其代码加载时间将为零。

    • 从而知道第一次加载应用程序代码(及其库)所花费的时间。链接器优化节省的时间应少于此上限。

    • 然后据此可以决定是否有必要这样对该应用进行链接优化。由于链接优化必须修改应用程序的编译方式,因此此类优化的成本很高。

       

    4.4.1 Prelink 预链接工具

    Prelink是Red Hat 开发者 Jakub Jelinek 所设计的工具,正如其名字所示,Prelink利用事先链接代替运行时链接的方法来加速共享库的加载,它不仅可以加快起动速度,还可以减少部分内存开销,是各种Linux架构上用于减少程序加载时间、缩短系统启动时间和加快应用程序启动的很受欢迎的一个工具。

    • 预链接减少了启动可执行文件所需的时间

    • 在Android上广泛使用

    • 必须配置为知道哪些库需要进行预链接,并将为每个可用符号分配一个固定的地址,从而消除了在启动可执行文件时重新定位符号的需要。

    • 请注意安全性,因为可执行代码始终加载在同一地址。

    • 代码以及文档参见

      http://people.redhat.com/jakub/prelink/

    • 支持ARM,但自2013年以来未发布。Buildroot也不支持。但是,x86比较容易实现。

     

    02 文件系统

    1. 文件系统

    不同的存储介质会采用不同的文件系统:

    1)块存储介质 (包括存储卡, eMMC):

    •  ext2, ext3,ext4

    •  xfs, jfs,reiserfs

    •  btrfs

    •  f2fs

    •  SquashFS 

     

    2)Raw 闪存:

    •  JFFS2

    •  YAFFS2

    •  UBIFS

    •  ubiblock +SquashFS

     

    对于块文件系统,特性各异:

    • ext4:最适合较大的分区,良好的读写性能。

    • xfs,jfs,reiserfs:在某些读或写场景中也可能很好。

    • btrfs,f2fs:利用闪存块设备的特性,可以实现最佳的读写性能。

    • SquashFS:对于只读分区,最佳挂载时间和读取性能。非常适合需要只读的根文件系统。

    下面分别介绍各文件系统的详细特性。

    1.1. JFFS2

    用于RAW Flash:

    • 挂载时间取决于文件系统的大小:内核必须在挂载时扫描整个文件系统,以读取属于每个文件的块。

    • 需要使用CONFIG_JFFS2_SUMMARY内核选项将此类信息存储在Flash中。这大大减少了安装时间。

    • ARM基准:对于128 MB分区,从16 s到0.8 s。

    • 与YAFFS2和UBIFS相比,读写性能相当差。

     

    1.3 YAFFS2

    用于RAW Flash:

    • 良好的安装时间

    • 良好的读写性能

    • 缺点:不压缩,不在主线Linux内核中

     

    1.4. UBIFS

    用于RAW Flash:

    • 优势:

      • 良好的读写性能(类似于YAFFS2)

      • 其他优点:更好的磨损均衡(不仅可以在单个分区内,而且可以在整个UBI空间中使用)。

    • 缺点:

      • 不适用于小型分区(元数据开销过多)。请改用JFFS2或JAFFS2。

      • 挂载时间不是很好,因为初始化UBI需要时间(UBI Attach:在引导时或在用户空间中运行ubi_attach)。

      • 由Linux 3.7中引入的UBI Fastmap解决

     

    1.5. UBI Fastmap如何工作

    • UBI 加载:需要通过扫描所有擦除块来读取UBI元数据。时间与存储空间成正比。

    • UBI Fastmap将此类信息存储在几个闪存块中(通常在系统关闭期间在UBI分离时),并在引导时找到该信息。

    • 这样可使UBI附加时间恒定。

    • 如果Fastmap信息无效(例如,不正常的系统关闭),它将退回到扫描状态(速度较慢,但能保证正确,Fastmap在下次启动时将恢复)。

    • 详细信息:Thomas Gleixner的ELCE 2012演讲:

      http://elinux.org/images/a/ab/UBI_Fastmap.pdf

    使用步骤:

    • 使用CONFIG_UBI_FASTMAP配置编译内核

    • 使用ubi.fm_autoconvert = 1内核参数至少引导一次系统。

    • 以干净的方式重启系统

    • 保证如上启动一次后可以删除ubi.fm_autoconvert = 1


    UBI Fastmap性能测试举例:

    • 在Linux 3.10的Microchip SAMA5D3 Xplained板(ARM)上测得

    • UBI空间:216 MB

    • 根文件系统:已使用80 MB(Yocto)

    • 平均加载时间:

      • 无UBI Fastmap,加载时间:968ms

      • 有UBI Fastmap,加载时间:238 ms

        可见UBI Fastmap 改善非常显著!

     

    1.6. ubiblock + SquashFS

    对RAW Flash :

    • ubiblock:位于UBI顶部的只读块设备

      利用CONFIG_MTD_UBI_BLOCK配置编译。

    • 允许将SquashFS放在UBI卷上。

    • 引导时间和读取性能不错。非常适合于只读根文件系统。

     

    2. 选取合适的文件系统

    • RAW Flash :带有CONFIG_UBI_FASTMAP的UBIFS可能是最佳解决方案。

    • 块存储:SquashFS是根文件系统的最佳解决方案,它可以是只读的。Btrfs和f2fs可能是读/写文件系统的最佳解决方案。

    • 更改文件系统类型非常容易,并且对应用程序完全透明。只需尝试几个文件系统选项,看看哪个最适合!

    • 不要只关注启动时间。

      对于读写性能至关重要的系统,我们建议使用单独的根文件系统(以加快启动时间)和数据分区(以实现良好的运行时性能)。

       

    2.1 Initramfs
    一个很好的方案是使用非常小的initramfs,以启动关键应用程序,然后切换到最终的根文件系统。

    图片

    initramfs机制:将根文件系统集成到内核映像中,因此它与内核一起被加载到内存中:

    • 它将文件系统的压缩存档集成到内核映像中

    • 变种:压缩的initramfs固件也可以由bootloader单独加载。

    initramfs在下面两种情况下非常有用:

    • 快速启动且非常小的根文件系统。由于文件系统在启动时已完全加载,因此应用程序启动也非常快。

    • 作为切换到实际根文件系统之前的中间步骤,该文件位于需要其驱动程序不属于内核映像的设备(存储驱动程序,文件系统驱动程序,网络驱动程序)上。始终在桌面/服务器发行版的内核上使用此选项,以保持内核映像大小合理。

     

    2.2 内存中的initramfs

    图片

    • 使用CONFIG_INITRAMFS_SOURCE选项在内核配置级别定义initramfs的内容

      • 可以是包含根文件系统内容的目录的路径

      • 可以是cpio归档文件的路径

      • 可以是描述initramfs内容的文本文件

    • 内核构建过程将自动获取CONFIG_INITRAMFS_SOURCE选项配置的内容,并将根文件系统集成到内核映像中

    • 详细信息(在内核源文件中):

      Documentation/filesystems/ramfs-rootfs-initramfs.txt

      Documentation/early-userspace/README

     

    2.3 用initramfs启动过程

    图片

    2.4 initramfs 降低启动时间

    创建尽可能小的最小初始化文件,足以启动关键应用程序,然后使用switch_root切换到最终根文件系统:

    • 使用轻量级的C库以减小固件大小,建议使用uClibc。

    • 将BusyBox裁剪到最小。甚至可以不用BusyBox直接在C中实现/init。

    • 使用静态链接的应用程序(较少的CPU开销,较少的库加载,较小的initramfs(如果根本没有库))。Buildroot中用BR2_STATIC_LIBS配置。


    2.5 静态链接可执行文件

    • 静态链接的可执行文件对于减小大小(特别是在小型initramfs中)非常有用,并且启动工作量较少。

    • 如果您将initramfs放在压缩的内核映像中,请不要对其进行压缩(启用CONFIG_INITRAMFS_COMPRESSION_NONE)。

    • 否则默认情况下,您的initramfs数据将被压缩两次,内核将更大,并且将花费更多的时间来加载和解压缩。

    • 在Linux 5.1上的示例在Beagle Bone Black上具有1.60 MB的initramfs(tar存档大小):这可以将内核大小从4.94 MB减少到4.74 MB(-200 KB),并节省大约170毫秒的启动时间。

     

    03 内核

    1.有用的调试手段

    1. 1 内核初始化度量函数

    要找出最长执行时间的内核初始化函数,请在内核命令行中添加initcall_debug。将内核日志中得到如下日志:

    图片

    如使用initcall_debug可能需要在内核配置中使用CONFIG_LOG_BUF_SHIFT增加日志缓冲区的大小。还可能需要使能CONFIG_PRINTK_TIME和CONFIG_KALLSYMS。

     

    1.2 使用内核启动图进行有目的的优化

    使用initcall_debug可以生成启动图,从而轻松查看哪些内核初始化函数需要最多时间来执行。

    • 复制dmesg命令的输出并将其粘贴到文件中(我们将其称为启动日志boot.log)

    • 在开发工作站上,在内核源代码中运行scripts / bootgraph.pl脚本:scripts / bootgraph.pl boot.log> boot.svg

    • 现在可以使用矢量图形编辑器(例如inkscape)打开启动图:

    图片

    首先从花费最长时间的功能开始尝试优化。对于每个功能:

    • 在内核源代码中查找其定义。

      可以使用Elixir(参考https://elixir.bootlin.com)。

    • 注意:某些函数名称可能不存在,名称与modulename_init相对应。然后,在相应的模块中查找初始化代码。

    • 删除不必要的功能:

    • 通过查看相应源目录中的Makefile,找到哪个内核配置参数可编译代码。

    • 延后加载处理:

      • 查找功能所属的模块(如果有)。如果可能,请稍后加载此模块。

    • 优化必要的功能:

      • 查找可以用于减少探测时间的参数,并查找module_param宏。

      • 查找延迟循环和对名称中包含delay的函数的调用, 可以减少此类延迟,并查看代码是否仍然有效。

     

    1.3 减小内核尺寸

    首先,我们专注于在不删除功能的情况下缩小尺寸

    • 主要机制是使用内核模块

    • 将启动时不需要的所有内容编译为模块

    • 有两个好处:内核更小且加载速度更快,初始化代码更少

    • 删除用户空间不需要的功能:

      CONFIG_KALLSYMS,CONFIG_DEBUG_FS,CONFIG_BUG

    • 用专为嵌入式系统设计的功能:CONFIG_SLOB,CONFIG_EMBEDDED

     

    然后考虑内核压缩的方式:

    根据存储读取速度和CPU解压缩内核之间的平衡,需要对不同的压缩算法进行测试。还建议在内核优化过程结束时尝试压缩选项,因为结果可能会因内核大小而异。

    图片

    在基于TI AM335x (ARM), 1 GHz, Linux 5.1测试:

     gziplzmaxzlzolz4
    大小2350336 1777000172012025338722716752
    拷贝0.208 s    0.158 s0.154 s0.224 s0.241 s
    启动时间1.451 s    2.167 s1.999s1.416 s1.462 s

    Lzo和Gzip似乎是最好的解决方案。 但这结果取决于存储和CPU性能,故在决定方案是务必进行测试。

     

    另外内核的编译选项也有可以优化的可能:

    • CONFIG_CC_OPTIMIZE_FOR_SIZE:可以使用gcc -Os而不是gcc -O2编译内核。

    • 这样的优化会优先考虑代码大小,但会牺牲代码速度。

    • 结果:初始引导时间更好(较小的启动时间),但是较慢的内核代码可能会使性能降低。系统运行速度会变慢!

     

    1.4 延迟驱动程序和初始化调用

    如果有点功能无法编译为模块(例如,网络或模块子系统),可以尝试推迟执行。内核不会缩小,但某些初始化将被推迟,所以启动变快。通常,您可以修改probe()函数以返回-EPROBE_DEFER,直到它们准备好运行为止。

    有关支持此功能的详细信息,请参见

    https://lwn.net/Articles/485194/。

     

    1.5 关闭控制台输出

    控制台输出实际上要花费很多时间(非常慢的设备)。 产品中可能不需要。通过在内核命令行中传递quiet参数来禁用它。但仍然可以使用dmesg获取内核消息。这一步一般建议等最后一步再做,否则将损失控制台进行调试。

     

    1.6 预置jiffy

    每次引导时,Linux内核都会校准延迟循环(用于udelay()函数)。这将测量每个jiff y(lpj)值的循环次数。只需要测量一次!在内核启动消息中找到 lpj值:

    Calibrating delay loop... 996.14 BogoMIPS (lpj=4980736)

    然后将lpj = <value>添加到内核命令行:

    Calibrating delay loop (skipped) preset value.. 996.14 BogoMIPS (lpj=4980736)

     

    1.7 多处理器

    SMP初始化很慢,即使您只有一个核心CPU,通常也会在默认配置中启用它(默认配置应支持多个系统)。因此,如果只有一个CPU内核,请确保将其禁用。BeagleBone Black上的结果:压缩内核大小:-188 KB

     

    要节省最后的毫秒数,您可能需要删除不必要的功能:

    • CONFIG_PRINTK = n与quiet命令行参数具有相同的效果,但是您无权访问内核消息。但是,您将拥有一个非常小的内核。

    • 在Thumb2模式下编译内核:CONFIG_THUMB2_KERNEL(任何ARM工具链都可以做到)。

    • 模块装卸

    • 块层(Block layer)

    • 网络堆栈

    • USB堆栈

    • 电源管理功能

    • CONFIG_SYSFS_DEPRECATED

    • 输入:键盘/鼠标/触摸屏

    • 减少CONFIG_LEGACY_PTY_COUNT的值或设置pty.legacy_count内核参数

     

    04 启动脚本

    1.优化初始化脚本和系统启动

    有多种方法可以减少启动应用程序之前执行启动脚本中花费的时间:

    • 仅在启动必要的依赖项之后,尽快启动应用程序。

    • 简化shell脚本

    • 可以尝试执行启动脚本之前启动应用程序

    1.1.bootchart

    如果想更详细地了解用户区的引导顺序,则可以使用使用grabserial中的bootchart来实现,例如:

    图片

    那么如何配置并使用bootchart 呢?

    • 在busybox中配置使用bootchartd(CONFIG_BOOTCHARTD = y)

    • 通过命令行init = / sbin / bootchartd 引导您的开发板

    • 将/var/log/bootlog.tgz从目标复制到开发主机

    • 生成时间表:

      cd bootchart-<version>

      java -jar bootchart.jar bootlog.tgz

      bootchart 参见 http://www.bootchart.org

     

    1.2. systemd

    如果将systemd用作初始化程序,则可以使用systemd-analyze。 

    http://www.freedesktop.org/software/systemd/man/systemd-analyze.html

    图片

    1.3. init 进程

    在所有依赖项启动之后,应尽快启动:

    • 取决于您的init进程。在这里,我们假设使用sysV init脚本。

    • init脚本按字母数字顺序运行,并以字母开头(K表示停止(杀死),S表示开始)。

    • 将应用程序启动脚本使用最小的号码。

    • 甚至可以用应用程序替换init!如果可以成为第一个启动的应用程序,启动速度无疑大大加快!

    • 直接通过一个启动脚本启动所有服务(例如/etc/init.d/rcS)。这消除了对/ bin / sh的多次调用。

    • 甚至可以直接在应用程序的C代码中挂载文件系统:如

    图片

     

    1.4 减少fork的使用

    • fork/exec系统调用开销很大。故从Shell调用可执行文件的速度很慢。

    • 即使BusyBox实现的shell中echo也会导致fork 系统调用!

    • 在BusyBox配置中选择Shells-> Standalone shell,以使Shell尽可能调用小程序。

    • 管道和反引号也由fork/exec实现。应减少它们在脚本中的使用。例:

      cat /proc/cpuinfo | grep model

      应修改为:

      grep model /proc/cpuinfo

      更详细,请参考:

      http://elinux.org/Optimize_RC_Scripts

       

      又例如:

      图片

      应做如下修改更佳:

      图片

      仅此一项优化就可以在ARM AT91SAM9263系统(200MHz)上节省87毫秒!

    1.5 减小固件的尺寸

    • 剥离可执行文件和库,删除仅用于开发和调试的ELF部分。strip命令由交叉编译工具链提供。默认情况下在Buildroot中完成的。

    • superstrip超级剥离

      http://muppetlabs.com/~breadbox/software/elfkickers.html。

      使用strip可以剥离出Linux未用于启动可执行文件的更多位。Buildroot停止支持它,因为它可能破坏可执行文件。 仅在保存一些字节至关重要时才尝试。

    • 还可以尝试https://packages.debian.org/sid/mklibs上提供的mklibs:

       

       mklibs产生精简的共享库,其中仅包含一组特定的可执行文件所需的例程。对于像OpenGL和QT这样的大型库确实很有用。它甚至可以在没有源代码的情况下工作。

      在Yocto中可用,但在Buildroot中不可用(2019.02状态)。

       限制:mklibs可以删除倾斜的库(由应用程序“手动”加载),因为它看不到它们

     

    3.5.5 快速启动画面显示

    • 可以使用fbv显示启动画面,

      http://freshmeat.sourceforge.net/projects/fbv

    • 使用armel,可以只使用我们的静态编译二进制文件:

      https://github.com/bootlin/static-binaries/tree/master/fbv/

    • 但是在MicrochipAT91SAM9263系统上很慢为878毫秒!

    • 为了更快地执行此操作,可以转储帧缓冲区framebuffer中的内容:

      fbv -d 1/root/logo.bmp

      cp /dev/fb0/root/logo.fb

      lzop -9/root/logo.fb

    •  然后尽早在initramfs中将其复制回:

      lzopcat/root/logo.fb.lzo > /dev/fb0


     

    05 Bootloader

    1. 裁剪

    • 删除不必要的功能。

      通常引导加载程序包括许多仅用于开发所需的功能。用较少的功能编译您的bootloader。

    • 优化所需的功能。调整引导加载程序以获得最快的性能。

     

    U-Boot是事实上的嵌入式bootloader标准,对于U-Boot而言,以下一些功能在产品中可能不需要:

    • 在include / configs / <soc>-<board> .h中禁用尽可能多的功能

    • 示例:MMC,USB,以太网,dhcp,ping,命令行版本,命令完成提示...

    • 较小且更简单的U-Boot加载速度更快,初始化速度更快。

    • 移除启动延时:

      • 消除启动延迟,这样通常可以节省几秒钟!:

        setenv引导延迟0

      • 在执行此操作之前,请先使用

        CONFIG_ZERO_BOOTDELAY_CHECK重新编译U-Boot,

        参考文档在doc / README.autoboot中。即使启动延迟设置为0,它也可以通过敲键来停止自动启动过程。

     

    2. 简化脚本

    有些情况,脚本很复杂,如:

    图片

    可以修改为:

    图片

    在ARM9(400MHz)可节省大约56ms

     

    3. 拷贝准确大小的内核

    • 将内核从ROM复制到RAM时,仍然看到许多系统复制了太多无用字节,而没有考虑确切的内核大小。

    • 在U-Boot中,使用nboot命令:

      nboot ramaddr 0 nandoffset

    • U-Boot使用存储在uImage标头中的内核大小信息来知道要复制多少字节。

     

    4. 优化内核加载

    将内核uImage复制到RAM之后,U-Boot始终将其移动到uImage标头中指定的加载地址。还执行CRC检查。

    • 可以通过将uImage直接加载到正确的地址来使U-Boot跳过memmove操作。

    • 计算此地址:

      Addr = Load Address - uImage header size

      Addr = Load Address - (size(uImage) - size(zImage))

      Addr = 0x20008000 - 0x40 = 0x20007fc0

    • 在生产中时数据一般不会损坏将内核复制到RAM时,可以考虑禁用CRC检查

    • 禁用带有U-boot环境变量的CRC检查:

      setenv verify no

    • 关闭U-Boot控制台输出。需要使用以下命令编译U-Boot

      CONFIG_SILENT_CONSOLE和setenv silent yes.

      有关详细信息,请参见doc / README.silent。

     

    5. 跳过bootloader直接启动内核

    • 原理:立即加载内核,而不是先加载引导加载程序,再加载内核!

    • 例如在Microchip AT91上,使用at91bootstrap v3即可轻松实现。
      您只需要使用linux或linux_dt配置之一进行配置:

      make at91sama5d3xeknf_linux_dt_defconfig

      make

    对于 U-Boot Falcon 模式:

    • U-Boot分为两部分:SPL(二级程序加载程序)和U-Boot映像。 然后,U-Boot可以配置SPL来直接加载Linux内核,而不是U-Boot映像。

    • 有关详细信息,请参见doc / README.falcon和

      http://schedule2012.rmll.info/IMG/pdf/LSM2012_UbootFalconMode_Babic.pdf进行原始演示。

    • 所有支持SPL的U-Boot板上均以相同的方式支持此功能。

    展开全文
  • 使用多张图片做动画的性能优化背景QQ群的送礼物功能需要加载几十张图然后做动画,但是多张图片加载造成了非常大的性能开销,导致图片开始加载到真正播放动画的时间间隔比较长。所以需要研究一些优化方案提升加载...
  • Transformers预测未来:关注下一时间序列预测 关注人工智能学术前沿 回复 :ts35 5秒免费获取论文pdf文档,及项目源码 摘要 直到最近,递归神经网络还是捕获时序相关性的最佳方法之一。然而,随着...
  • 01. 同步(LockStep)该如何反外挂 在中国的游戏环境下,反挂已经成为了游戏开发的重中之重,甚至能决定一款游戏的生死,吃鸡就是一个典型的案例。 目前参与了了一款动作射击的MOBA类游戏的开发,同步方案上选择...
  • 启动时间优化毫无疑问,应用的启动速度越快越好。本文可以帮助你优化应用的启动时间:首先描述应用启动过程的内部机制;然后讨论如何分析启动性能;最后,列举了一些常见的影响启动时间的问题,并就如何解决这些问题...
  • Canvas性能优化

    2021-06-12 13:55:39
    渲染动画的基本原理无非是反复的擦除和重绘。为了动画的流畅,留了一时间,我们需要在16ms完成游戏...所以提高动画的性能很重要3、优化渲染性能总体思路:在每一中,尽可能减少调用渲染相关的API次数在每一...
  • 查看数 在while循环的末尾添加如下代码 glfwPollEvents(); //立即处理已经到位的事件,如果没有这个就会一直渲染而不触发事件 glfwSwapBuffers(window); modelPicking(); static int ticks = -1; ticks+...
  • 点击上方“3D视觉工坊”,选择“星标”干货第一时间送达参考论文:Polygonal Building Extraction by Frame Field Learning(CVPR2021...
  • JVM 性能优化

    2021-02-18 17:35:26
    JIT的构成组件为: 中间代码生成器(Intermediate Code Generator):生成中间代码 代码优化器(Code Optimizer):负责优化上面生成的中间代码 目标代码生成器(Target Code Generator):负责生成机器代码或本地...
  • 1、逻辑驱动归一管理,这个主要是要将战斗过程的所有逻辑运算update驱动要统一管理,而不是简单的通过UI 层的update分散驱动,这样做的话你的update是不确定的,这里的确定分两部分1)执行时间上的确定性,2...
  • 1.启动页 2.Application启动优化 3.关闭APP优化 4.启动时间分析 5.常用启动分析工具
  • Android应用启动优化

    2021-01-11 11:10:24
    本文档提供的信息可以帮助您优化应用的启动时间。首先介绍启动过程的内部机制。然后,讨论如何剖析启动性能。最后,介绍一些常见的启动时间问题,并给出一些有关如何解决这些问题的提示。 了解应用启动内部机制 应用...
  • Unity项目优化

    2021-07-27 14:55:25
    导航网格 NavMesh.SamplePosition采样距离由 50 改为 2,25,50三段采样,调用七次的时间从 3.4ms 降至 0.86ms,CPU消耗减少6%左右 带有Animator组件的Object频繁的SetActive会导致性能警告,使用移出屏幕的...
  • 来源:IEEE编辑:新智元【导读】稀疏人脸特征点生成的人脸图像视频通常会遇到图像质量损失、图像失真、身份改变,以及表情不匹配等问题。为此作者使用重建出的三维人脸动态信息来指导人脸视频的生成...
  • iOS之深入探究动画渲染降

    万次阅读 2021-10-16 20:50:40
    一、为什么要对动画降? 众所周知,刷新频率越高体验越好,对于 iOS app 的刷新频率应该是越接近越 60fps 越好,主动给动画降,肯定会影响动画的体验。但是另一方面,我们也知道动画渲染的过程中需要消耗大量的...
  • CPU优化

    2021-01-11 16:40:17
    CPU优化主要关注“卡顿”的,即CPU耗时较长的。关于CPU优化有一下几点建议: 1. Unity中利用控制台输出是非常占用CPU的,无论是Debug.Log()还是print()。生成的程序在应用时依旧会输出日志,因此程序正式发布时...
  • 同步的一些坑

    2021-01-17 15:31:08
    一. 简述我们用最精简的模型来描述一下同步。客户端检测服务器的逻辑 -> 拿到逻辑 -> 进行处理 ->... 结束在此基础上,客户端可以通过缓存,平滑,预测,插值,等方案优化表现层的效...
  • OpenGL 缓冲Framebuffers

    2021-03-19 17:25:56
    OpenGL缓冲Framebuffers缓冲Framebuffers简介创建一个缓冲纹理附件渲染缓冲对象附件渲染到纹理后期处理反相灰度核效果模糊边缘检测 缓冲Framebuffers简介 到目前为止,我们已经使用了很多屏幕缓冲了:用于...
  • 该框架还包含一种 3D Nearby Attention (3DNA) 机制,以考虑空间和时间上的局部特征。3DNA 不仅降低了计算复杂度,还提高了生成结果的视觉质量。与几个强大的基线相比,「女娲」在文本到图像生成、文本到视频生成、...
  • 图 3 本方法提出的FACIAL-GAN网络结构框架 如图3所示,FACIAL-GAN 由三个基本部分组成:时间相关生成器用于构建上下文关系和局部语音生成器用于提取每一特征。此外,使用判别器网络来判断生成的属性的真假。...
  • 1 以太网交换机工作原理 以太网是当今现有局域网采用的最通用的通信协议标准。 以太网交换机是基于以太网传输数据的...结构:以太网的是数据链路层的封装,网络层的数据包被加上头和尾成为可以被数据链...
  • 点击上方“AI算法与图像处理”,选择加"星标"或“置顶” 重磅干货,第一时间送达 从事算法岗经常需要查看最新的研究成果,希望从中能借鉴一些别人的思路。全世界每天更新的成果...
  • 前言对程序员们来说,代码优化是一个很重要的课题。可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?...但是如果有足够的时间开发、维护代码,这时候就必...
  • 用 JavaScript 实现时间轴与动画 - 前端组件化

    千次阅读 多人点赞 2021-04-05 09:06:09
    这样我们 Timeline(时间线)中的时间就开始以 60 的播放率开始运行。 最后代码就是如下: const TICK = Symbol('tick'); const TICK_HANDLER = Symbol('tick-handler'); export class Timeline { constructor() {...
  • 作者丨宁欣,南方哲,许少辉,于丽娜,张丽萍审稿丨邓富城编辑丨极市平台导读本文将重点对近些年来基于3D模型和深度学习模型的人脸正面化生成方法的主要进展和部分具有代表性的研究成果进行介绍,并...
  • 由于Fps,内存,Cpu等都是需要频繁采样的,比如Fps,一秒钟刷新60,如果全量数据上报,那么后端大佬可能就把我给打死了。 在业务最少介入的情况下完成关键页面数据的收集,以及将页面数据和性能数据进行绑定。 ...
  • 激光雷达里程计因子的生成步骤如下: 1)体素地图的子关键(Sub-keyframes):我们实现了一个滑动窗口的方法来创建一个包含固定数量的最近激光雷达扫描的点云地图。我们没有优化两个连续的激光雷达扫描之间的转换,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 47,955
精华内容 19,182
关键字:

帧生成时间优化