游戏引擎学习第14天

news2024/11/18 15:03:38

视频参考:https://www.bilibili.com/video/BV1iNUeYEEj4/

1. 为什么关注内存管理?

  • 内存分配是潜在的失败点

    • 每次进行内存分配(mallocnew等)时,都可能失败(例如内存不足)。
    • 这种失败会引入不稳定性或不可预测性,需要额外的错误处理逻辑。
  • 传统编程的理念

    • 在“老派编程”中,作者更倾向于避免动态内存分配,通过静态或固定大小的缓冲区管理内存,从而使程序更加稳定和可靠。

2. 如何避免动态内存分配?

  • 示例中使用的策略
    • 程序需要两个缓冲区(一个音频缓冲区和一个位图缓冲区),它们通过操作系统一次性分配完成,且在整个程序生命周期内从不释放(never freed)。
    • 这种设计消除了动态内存分配的风险,也避免了与内存回收(如垃圾回收)相关的复杂性。

3. 动态内存分配的挑战

  • 现代编程环境的现状

    • 现代程序大量依赖动态内存分配和垃圾回收(如Java、C#中的GC机制)。
    • 动态内存管理可能导致性能抖动(如虚拟内存分页),难以预测程序的行为。
  • 作者的观点

    • 过多依赖动态内存分配,使得程序开发变得复杂且不可控。
    • 作者更喜欢“静态内存分配”或“固定缓冲区”的方法,使程序从一开始就处于稳定状态。

4. 静态内存管理的优点

  • 高可靠性

    • 程序一旦启动,就不会因为内存问题而失败。
  • 简单性

    • 减少内存泄漏和回收相关的复杂性。
  • 性能一致性

    • 消除了垃圾回收或虚拟内存分页带来的性能抖动。

5. 哲学层面的思考

  • 作者更喜欢探索传统编程中的一些“简单且有趣”的做法,比如尽可能避免动态内存分配。
  • 他认为,这种方法可以让编程回归本质——精心设计和实现代码,而不是依赖现代编程环境中的各种工具和机制。

这段视频主要在讨论内存分配的优化以及游戏开发中不同的设计思路。以下是对这段对话的简要总结:

  1. 内存分配策略

    • 演讲者建议采用预分配内存的方式,而不是在运行时频繁分配。
    • 他提到这种方法类似“旧学校”的平分区策略,即一开始抓取一块大内存,并为每个子系统预先分配固定的空间。
  2. 静态变量的使用

    • 演讲者提到使用 static 定义的“局部持久变量”,它本质上是一种作用域限制在函数内的全局变量。
    • 他不喜欢这种设计,因为它可能导致代码混乱和难以维护。
  3. 传统与现代的差异

    • 他对比了旧式街机程序员的开发风格和现代普遍的“内存分配狂欢”方法。
    • 强调大多数现代游戏不会采用他的方式,但他认为提供不同的视角是有意义的。
  4. 未来设计计划

    • 他计划展示如何将游戏状态存储在预先分配的内存中。
    • 演讲者希望避免动态分配,并使用更高效的方式管理内存。
  5. 强调多样化的视角

    • 演讲者明确指出,他并不是在提倡大家完全采用他的方式,而是提供一种不同的思考方式。

这种方法对某些嵌入式系统或资源受限的环境可能很有帮助,但在资源丰富的现代系统中可能并不常见。您对这段内容是否还有特定部分需要进一步解析?

在某些编程或系统设计情况下,处理失败案例的挑战,特别是与内存分配相关的挑战。

  1. 失败案例的策略

    • 必须有一个处理失败案例的计划。例如,每当进行新的资源分配时,需要检查分配是否成功,并妥善处理可能的失败情况。这可能需要复杂的逻辑来处理多种路径的成功或失败。
  2. 现实中的折中策略

    • 一种方法是通过测试运行系统,观察其内存使用情况,并确保启动时分配足够的内存。
    • 使用自定义分配器,预先分配一定的内存以避免运行中内存不足,但这种方法依赖于测试的全面性。
  3. 未知风险的接受

    • 有时,只能假设程序不会超出所需的内存范围,希望玩家或用户不会触发未考虑到的极端场景。这种方法依赖于假设和希望,而不是完全可靠的保障。
  4. 故事的必要性

    • 在设计系统时,需要为失败场景找到一个“故事”或策略,即使有时故事仅仅是“不清楚,但在测试中未发现问题”。
  5. 个人观点

    • 作者对这些策略并不满意,认为这些都不是理想的答案,但在实践中可能不得不接受其中之一。

平台抽象设计中关于游戏与平台之间交互的复杂性,以及如何简化这种交互。以下是总结:

  1. 循环调用的缺点

    • 游戏和平台之间频繁的双向调用(循环调用)会增加复杂性,使得理解两者之间的关联变得更加困难。
    • 这种复杂性在高级功能(如记录和回放整个游戏会话以进行调试)中尤为明显。
  2. 推荐的设计方式

    • 建议设计为简单的数据流模式:
      • 平台作为服务请求游戏提供必要的数据(如视频帧、音频输出等)。
      • 输入(如用户操作)直接传递到游戏,输出直接返回到平台。
    • 避免游戏层再调用平台,这种方式可以减少系统的耦合性,简化回放系统的实现。
  3. 单线程时代的优势

    • 在过去的单线程环境中,这种输入流和输出流定义明确的设计简化了调试工作(例如回放游戏的整个会话)。
    • 单一输入和输出流的模型使得系统在逻辑上更容易追踪和复现问题。
  4. 多核时代的挑战

    • 如今由于多核架构的普及,线程化操作增加了复杂性,使回放系统变得困难。
    • 线程化问题导致这种设计在现代环境中不再像过去那样具有优势。
  5. 结论

    • 过去单线程的设计逻辑有其历史意义和现实效率,但在现代多线程环境中,需要权衡线程管理的难度和系统简单性之间的关系。

游戏开发中的内存管理哲学进行了讨论。以下是要点总结:

  1. 内存管理的责任分配

    • 平台层在游戏启动时分配一块大内存给游戏。
    • 游戏负责对这块内存进行进一步分区和管理。
    • 游戏内的所有系统都必须在一个固定的内存空间中操作,确保游戏启动后能够运行至结束而不会因内存问题失败。
  2. 可靠性目标

    • 游戏开发的目标是做到“一旦启动,就不会失败”。
    • 即使某些资源(如精灵)丢失,游戏仍然能够正常运行。
    • 平台层可能会由于操作系统的问题而失败(例如 Windows 的设计缺陷),但这不会影响游戏的整体可靠性。
  3. 资源管理的哲学

    • 开发中采用“零失败状态”原则,即尽量减少游戏运行中的错误。
    • 提议了“金银铜”标准,以根据不同游戏的复杂程度评估其达到可靠性目标的水平。
  4. 延伸到磁盘 I/O

    • 与内存管理类似,对磁盘 I/O 的管理也遵循相同的哲学,以尽量减少失败。

作者表示,动态分配本质上是一种"自欺欺人"的做法,因为它假设内存是无限的,而实际上硬件的内存是有限的。如果不控制内存使用,程序可能会在运行时遇到不可预见的问题,如内存不足或碎片化。
采用主存池的方案,可以保证程序在固定内存下运行,减少风险。尤其是在面向最终用户的产品中,确保内存不会超出限制并且程序能顺利启动和运行是非常重要的。
1:03:31Why use the void* in game_memory?
在这段字幕中,主要的内容涉及内存管理和如何在游戏中处理不确定类型的内存块。可以从中提取出以下几个关键点:

  1. 不确定的内存块:由于游戏内存的某些部分是不确定的,我们不能为这些部分指定类型。这些部分被视为一个“大内存块”,游戏可以根据需要任意处理这些内存数据。

  2. void指针:提到使用空指针(或void指针)来指示这些不确定的内存块。因为我们不知道它们的具体类型,所以使用void指针来管理这些内存是一个常见的做法。

  3. 类型转换:虽然开始时内存块没有明确的类型,但可以在后续转换成具体的游戏状态或其他类型,并开始进行类型化管理。

  4. 游戏中的使用:游戏开发中常常需要处理各种类型的内存,这些内存数据可以根据需求灵活地操作和转换成具体的类型。

  5. “冷启动”和“冷转换”:提到的“冷启动”和“冷转换”暗示着这些内存块被快速转换成所需的格式,过程没有太多的复杂操作,直接转换为游戏所需要的状态。

  6. 游戏规模的影响:由于游戏的规模可能很大,这种内存处理方法显得尤为重要,能够动态地应对不同类型的内存需求。

存储管理和游戏开发中的一些技术概念。可以理解为以下几点:

  1. 永久存储和临时存储的区分

    • 永久存储:指的是游戏在运行过程中必须保持的数据,这些数据对游戏的持续运行至关重要,例如玩家的进度、已解锁的内容等。
    • 临时存储:是一些临时存储的数据,可以在不影响游戏运行的情况下清除或重新加载,例如缓存的纹理、声音等资源。
  2. 区分的原因

    • 性能优化:临时存储的数据可以被刷新(如在游戏运行时清空缓存),这有助于优化性能,减少内存占用。比如,在iPhone等设备上,清空缓存有助于减少应用的内存占用。
    • 事件驱动:临时存储的数据可能会受到某些事件的影响(例如用户的操作或系统事件),而这些数据不一定需要长期保存。
  3. 为什么分开处理

    • 这样做是为了能够对数据进行更灵活的管理,例如在需要时清除临时存储的数据,而不会影响到永久存储中的重要数据。
    • 这种区分还有助于一些额外的优化技巧,例如缓存和重新加载过程的优化。
  4. 后期调整

    • 在开发过程中,可能会根据实际需求调整永久和临时存储的具体实现,这种调整是灵活的,因此开发者可能会先写好代码框架,再根据实际情况做修改。

避免在平台层和游戏层之间进行频繁往返调用(即“往返旅行”),这种设计模式可能导致系统中的复杂性和性能问题。以下是一个简要的总结:

  1. 避免内存分配的往返:谈话的重点之一是避免频繁在平台层和游戏之间进行内存分配的往返。这种“往返旅行”指的是平台层调用游戏层,游戏层再调用回平台层,从而引入不必要的复杂性和性能开销。

  2. 虚拟化的例子:提到一个虚拟化的例子,试图通过设计避免频繁的内存分配和平台调用之间的交互,这样可以减少系统中的“蜘蛛网”式的复杂关系。

  3. 堆栈和调用关系:系统中创建了一个堆栈,其中平台层和游戏层交替调用,这种结构可能导致管理上的困难,尤其是当每个组件由不同的开发人员编写时。

  4. 简化设计:最后提到的优化建议是,如果设计得当(比如通过传递合适的参数),可以简化整个调用结构,使得系统运行更加高效且易于维护。

总的来说,这段对话强调了通过避免复杂的相互依赖关系和频繁的内存分配,可以让系统变得更高效、更简洁。

下面是平台独立内存代码的修改

在这里插入图片描述

任务管理器查看内存提交的大小

在这里插入图片描述

vscode 的一个小插件

在这里插入图片描述

    "workbench.colorCustomizations": {
        // 新增文本的背景颜色
        "diffEditor.insertedTextBackground": "#00501388", // 浅绿色,带透明度
        // 删除文本的背景颜色
        "diffEditor.removedTextBackground": "#62000088", // 浅红色,带透明度
        // 修改区域的边框颜色(可选)
    },

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

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

相关文章

基于Java Springboot电商个性化推荐系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA/eclipse 数据…

react中如何在一张图片上加一个灰色蒙层,并添加事件?

最终效果: 实现原理: 移动到图片上的时候,给img加一个伪类 !!此时就要地方要注意了,因为img标签是闭合的标签,无法直接添加 伪类(::after),所以 我是在img外…

基于Java Springboot拍卖行系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA/eclipse 数据…

HTML5+CSS前端开发【保姆级教学】+前端介绍和软件安装

学习了基础编程刚刚开始学习计算机的程序员,你是否会这样的想法:前端和后端是什么呢?如果你是刚上大学的大一大二基础小白,但是身边的卷王同学已经超前知道之后要从事前后端开发了,并且在学习各种框架的课程,Aahhahah,…

Android Framework层介绍

文章目录 前言一、Android Framework 层概述二、主要组件1. 应用程序接口(API)2. 系统服务3. Binder4. 资源管理5. Content Provider6. 广播接收器(BroadcastReceiver)7. 服务(Service) 三、与 Linux Kerne…

【C++滑动窗口】1248. 统计「优美子数组」|1623

本文涉及的基础知识点 C算法:滑动窗口及双指针总结 LeetCode1248. 统计「优美子数组」 给你一个整数数组 nums 和一个整数 k。如果某个连续子数组中恰好有 k 个奇数数字,我们就认为这个子数组是「优美子数组」。 请返回这个数组中 「优美子数组」 的数…

【paper】分布式无人水下航行器围捕智能目标

An Effective Strategy for Distributed Unmanned Underwater Vehicles to Encircle and Capture Intelligent Targets2022.8IEEE TRANSACTIONS ON INDUSTRIAL ELECTRONICS【Q1 7.5】Mingzhi Chen 上海理工大学 Q1 Background:本文试图解决一个什么样的问题&#xf…

【更新中】《硬件架构的艺术》笔记(三):处理多个时钟

介绍 单时钟设计更易于实现,也更少出现亚稳态、建立和保持时间违例方面的问题。但在实践中,很少有设计只在一个时钟下运行。 多时钟域 多个始终可以有以下一种或多种时钟关系: 1、时钟频率不同。 2、时钟频率相同,但相位不同…

Python_爬虫1_Requests库入门

目录 Requests库 7个主要方法 Requests库的get()方法 Response对象的属性 爬取网页的通用代码框架 理解requests库的异常 HTTP协议及Requests库方法 HTTP协议 HTTP协议采用URL作为定位网络资源的标识。 HTTP协议对资源的操作 理解PATCH和PUT的区别 HTTP协议与Requse…

从客户需求视角去认识ZLG | 边缘计算网关多种应用

在工业领域,串行总线与EtherNET总线广泛应用,物联网的兴起带来众多智能应用。尽管应用多样,但底层技术逻辑却殊途同归,本文将介绍ZLG致远电子串行总线和EtherNET总线之间的联动应用。 本文将从系统集成需求出发,以ZLG致…

Koa进阶:掌握中间件和参数校验的艺术

目录 一、首先下载依赖 二、在index.js中引入koa-parameter,一般挂载这个中间件时会放在注册请求体的后面 三、使用实例 四、如果跟我们所需求的参数不同,返回结果直接会返回422 koa-parameter一般是用来校验请求传过来的参数是否是自己所需要的的 G…

Linux下使用miniconda构建python运行环境

文章目录 miniconda安装构建python运行环境 miniconda安装 miniconda在linux环境下载安装: # Linux环境下使用wget命令下载选定的miniconda # 这里使用的是清华镜像,这个命令每次下载的是最新版本的miniconda wget -c https://mirrors.tuna.tsinghua.e…

解决failed to execute PosixPath(‘dot‘) 或者GraphViz‘s executables not found

在网上找了很多方法都没解决,所以写一篇文章帮助和我遇到同样问题的人 解决方法: 因为python解释器会解释转移字符,因此在环境变量中把\bin换成\\bin即可 解决过程: 系统:win10 已安装pip install graphviz&#xff0…

Deep-Live-Cam -面部交换、视频深度伪造

文章目录 一、关于 Deep-Live-Cam免责声明 二、安装(Windows/Nvidia)安装(手动)基本安装(CPU) GPU加速(可选)CUDA执行提供商(Nvidia)CoreML执行提供商&#x…

计算机毕业设计Python美食推荐系统 美团爬虫 美食可视化 机器学习 深度学习 混合神经网络推荐算法 Hadoop Spark 人工智能 大数据毕业设计

温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…

Scala-数据类型-概述(Scala 3.x 类型层次结构)

Scala Scala-数据类型 Scala1. Any — 顶级类型2. Matchable — 匹配类型3. AnyVal — 值类型的父类4. AnyRef — 引用类型的父类5. Null - 引用类型的子类型Tips: 为什么 null 不推荐使用? 6. Nothing - 底层类型 (Bottom Type)整理不易,对您有帮助的话…

嵌入式linux中红外接收基本方法分析

大家好,今天主要给大家分享一下,如何使用Linux系统中的红外接收驱动控制方法。 第一:Linux红外基本简介 红外遥控是我们常见的一种无线收发设备,具有抗干扰能力强,功耗低,成本低,易实现等优点。被很多电子设备特别是家用电器广泛采用,如电视遥控、空调遥控等。红外遥控…

AWTK-WIDGET-WEB-VIEW 实现笔记 (2) - Windows

在 Windows 平台上的实现,相对比较顺利,将一个窗口嵌入到另外一个窗口是比较容易的事情。 1. 创建窗口 这里有点需要注意: 父窗口的大小变化时,子窗口也要跟着变化,否则 webview 显示不出来。创建时窗口的大小先设置…

pgAdmin简单介绍

pgAdmin介绍 官网:https://www.pgadmin.org/ pgAdmin is the most popular and feature rich Open Source administration and development platform for PostgreSQL, the most advanced Open Source database in the world. pgAdmin may be used on Linux, Unix…

Linux笔记---调试工具GDB(gdb)

1. gdb的概念 GDB,全称GNU Debugger,是一个功能强大的开源调试工具,广泛用于Unix和类Unix系统,以及Microsoft Windows和macOS平台。GDB允许开发者在程序执行过程中查看内部运行情况,帮助定位和修复程序中的错误。 gd…