一文带你读懂MLIR论文,理解MLIR设计准则.

论文MLIR: Scaling Compiler Infrastructure for Domain Specific Computation

MLIR:针对特定领域计算扩展编译器基础设施

文章目录

  • 论文MLIR: Scaling Compiler Infrastructure for Domain Specific Computation
    • 1. 论文下载
    • 2. TVM关于MLIR的讨论
    • 3. 论文正文
      • 0. 摘要
      • 1. 导论
        • 1.1 贡献
        • 1.2 MLIR 为了解决什么问题?
      • 2. 设计准则
    • 3. IR 设计
    • 参考

1. 论文下载

链接: https://pan.baidu.com/s/1IJ_ZuD4NX5n2TWWEhQefmQ?pwd=rkqw 提取码: rkqw 复制这段内容后打开百度网盘手机App,操作更方便哦

在正式开始阅读MLIR论文前,我们先一起看下TVM社区的大佬们,对MLIR有哪些见解,感受下圈内大佬的视角.

2. TVM关于MLIR的讨论

  • TVM- Google-lasted-work-mlir-primer

我在学习MLIR的时候,里面的一些概念让我很是恼火呀, 每一个字我都认识,看完却不知道ta究竟在讲什么.所以我就搜集了网上各路人马对MLIR的博客,评价等.

收集了一些好玩的观点,在这里简短记录一下.

  • 观点一: MLIR就是XML
    • tianqi大佬说MLIR有点像XML, 这个角度很轻奇. 当初我看到这个观点的时候有点不太理解, 后来通读了MLIR的文档后,发现果然不愧是圈内大佬,一言概括了MLIR的核心工作.

image-20240714140011746

  • 然后有人对大佬提问: 担心MLIR把TVM饭碗打翻了不?
    • MLI R的方言在各个领域定义,并且有对应的pass,与LLVM紧密联系,会让MLIR的IR更接近底层.
    • TVM的I R相对于MLIR的IR来说就更加上层,我们的pass和IR看起来就像是对MLIR的包装.

image-20240714143118873

  • 大佬对其进行了回应

image-20240714143504242

image-20240714143657116

  • 大佬还提了一嘴TVM的原则

image-20240714143931386

  • 这个好像是知乎的蓝色大佬?

image-20240714140328194

  • 有人觉得MLIR这个是对ONNX的回应?

image-20240714142427918

  • TVM如何快速支持tensorflow?
    • MLIR做前端, TVM做后端: 讨论?

image-20240714144622279

  • 以上讨论是2019年的, 截止2022年,有人发帖询问为什么社区还没实现?

image-20240714145024981

简单搜索了一下,目前TVM和MLIR是🈶2个项目在做的.

在这里插入图片描述

  • 项目对比
    在这里插入图片描述

我们开始正式了解MLIR吧~

3. 论文正文

0. 摘要

研究背景、研究问题、研究目的和研究的意义

一种构建可重用和可扩展编译器基础设施的新方法。 MLIR 解决了软件碎片问题、异构硬件编译问题,显着降低了构建特定领域编译器以及将现有编译器连接在一起的成本。

MLIR 在不同的抽象层次,不同应用领域,不同硬件目标和不同执行环境下加快代码生成器,翻译器和优化器的设计和实现。

主要贡献:

  1. 从研究的角度探讨MLIR 的扩展和演进,给出该方法在设计、语义、优化、系统及工程方面的机遇与挑战
  2. 评估 MLIR 作为一种通用基础设施,在降低构建编译器的成本方面的功效如何,通过多个实际案例来展示未来在编程语言,编译器,执行环境和计算机体系结构方面的科研教育的机会.
  3. 本文还介绍了 MLIR 的基本原理、其原始设计原则、结构和语义。

1. 导论

研究背景

​ 译器设计是一个有着广泛的知名算法的成熟领域,在代码生成,静态分析,程序变换方面有广泛应用。这个领域也有许多成熟的技术和平台,这些平台使得不同的编译器社区能够大量复用已有技术,包括 LLVM 编译器基础架构,JAVA虚拟机诸如此类。这些成熟系统的一个共同点是“一体多用”(one size fits all)——系统接口只有一套抽象:LLVM 中间表示(IR)基本上可以看成是带向量的C(C with vectors),JVM提供了一个“带垃圾回收的面向对象的类型系统”抽象。这种“一体多用“的方案相当有价值——在实践中,从不同的源语言(C/C++或者JAVA)到这些领域的映射很直接。

​ 与此同时,许多问题在一个high-level 或者 low-level 的抽象层次上更容易建模——如,在LLVM IR 上进行C++的源码级分析就十分困难。我们发现许多语言(包括swift,rust,juia,fortan)设计自己的 IR 以便解决语言/库相关的优化,控制流敏感的类型检查(eg 线性类型),优化 lowering 过程实现等领域特定的问题。类似的,机器学习也采用类似的方法,使用“ML图”(ML graph)作为领域特定抽象。所以MLIR就想要提供一个通用的IR,用于各个领域.

研究问题

虽然特定领域 IR 的开发是一门经过充分研究的艺术,但其工程和实施成本仍然很高。对于这些系统的实施者来说,基础设施的质量并不总是首要任务(或容易证明其合理性)。因此,这可能会导致编译器系统质量较低,包括用户可见的问题,例如编译时间慢、执行错误、诊断质量欠佳、优化代码的调试体验差等。

研究目的

MLIR 项目旨在直接解决这些编程语言设计和实现挑战 -MLIR 项目通过低成本地设计和引入新的抽象层,,并提供“内置”“开箱即用”(in the box)基础设施来解决常见的编译器工程问题。 MLIR 通过

(1) 标准化基于静态单分配 (SSA) 的 IR 数据结构 ( 理解SSA )

(2) 提供用于定义 IR 方言的声明性系统 (ODS,DDR)

(3) 提供广泛的通用基础设施,包括文档,解析和打印的逻辑,位置跟踪,多线程编译支持,PASS 管理等。

本文进一步介绍了 MLIR 设计和实现的总体原则。我们将探讨系统的基本设计点以及它们与总体原则的关系,并分享我们将 MLIR 应用到许多编译问题的经验。

1.1 贡献

大多数 MLIR 系统都是根据众所周知的概念和算法构建的。然而目标和设计已经足够研究它们提供了巨大的研究机会,

设计原则

  • 简约

    • 将奥卡姆剃刀应用于内置语义、概念和编程接口。通过抽象操作和类型的属性来利用内在和附带的复杂性。指定一次不变量,但始终验证正确性。在给定编译过程的上下文中查询属性。只需很少的内置功能,这就为可扩展性和定制性打开了大门。

      • 奥卡姆剃刀的核心思想是:

        如无必要,勿增实体。

        也就是说,在面对多个解释或假设时,应该选择最简单的那个,不要引入不必要的复杂性。

  • 可追溯性

    • 保留而不是恢复信息。声明规则和属性以启用转换,而不是逐步命令式规范。可扩展性伴随着跟踪信息的通用方法,并通过广泛的验证来强制执行。可组合抽象源于“玻璃盒”其属性并分离其角色——类型、控制、数据流等。
  • 渐进性

    • 过早降低是万恶之源。除了表示层之外,还允许多种转换路径,以降低各个区域的需求。与抽象无关的原则和接口一起,这使得跨多个域的重用成为可能。

虽然这些原则已得到充分确立,但其中一项原则的实施往往以牺牲另一项原则为代价;例如,网络和操作系统堆栈中的分层符合渐进原则,但打破了简约性。具有多层 IR 的编译器也是如此。此外,遵循这些原则可能会损害表达力和有效性;例如,安全关键型和安全系统中的可追溯性涉及限制优化及其攻击性。

简而言之,我们确定了编译器构建的设计和工程原则,以便在支持开放语义生态系统的狭窄中间蓬勃发展。我们发现可以在不限制表达能力的情况下控制复杂性,从而允许跨领域进行快速 IR 设计探索和整合,而这两者在生产系统中都严重缺乏。

本文的贡献是

  1. 根据经过验证的设计和工程原理,构建可扩展和模块化编译器系统;
  2. 遵循这些原则的新型编译器基础设施的描述,具有重要的工业和研究应用;
  3. 探索了几个 MLIR 在多个领域的应用.分享基于MLIR 基础设施的开发系统的经验。
1.2 MLIR 为了解决什么问题?

MLIR 的工作始于认识到现代机器学习框架由许多不同的编译器、图形技术和运行时系统组成.而这些框架并不共享通用的基础设施或设计原则。这以多种用户可见的方式表现出来,包括糟糕的错误消息、边缘情况下的故障、不可预测的性能以及难以推广堆栈以支持新硬件。

image-20240624195531593

我们很快意识到整个编译器行业也存在类似的问题:像 LLVM 这样的现有系统非常糟糕。

成功地统一和集成了一系列不同语言的工作,但高级语言通常最终会构建自己的高级 IR 并重新发明相同类型的技术以实现更高级别的抽象,与此同时,LLVM 社区在并行结构的表示以及如何共享前端降低基础设施(例如 C 调用约定或 OpenMP 等跨语言功能)方面遇到了困难,但没有令人满意的解决方案。

image-20240624195543116

面对这一挑战,考虑到我们无力实现N个改进的编译器实例,我们决定寻求更通用的解决方案:投资高质量的基础设施,使多个领域受益,逐步升级现有系统,更容易解决紧迫的问题诸如专用加速器的异构编译等问题,并提供新的研究机会。现在,我们在构建和部署基于 MLIR 的系统方面积累了大量经验,我们能够回顾其基本原理和设计,并讨论为什么要追求这个方向。

2. 设计准则

  • 尽可能少的内置,尽可能多的定制(Little Builtin, Everything Customizabl)

    • 该系统基于最少数量的基本概念,使大部分中间表示完全可定制。 IR 中最常见的一些抽象(类型、操作和属性)应该用于表达其他所有内容,从而允许更少且更一致的抽象,从而易于理解、扩展和采用。从广义上讲,可定制性确保系统能够适应不断变化的需求,并且更有可能适用于未来的问题。从这个意义上说,我们应该将 IR 构建为一个丰富的基础设施,其中包含可重用的组件和支持其中间语言的语法和语义的编程抽象。
    • 定制的成功标准是表达多种抽象的可能性,包括机器学习图、AST、多面体等数学抽象、控制流图 (CFG) 和指令级 IR(例如 LLVM IR)都无需将这些抽象概念硬编码到系统中。
    • 当然,由于抽象兼容性差,可定制性会产生内部碎片的风险。虽然不太可能有纯粹的技术解决方案,但系统应该鼓励人们设计可重用的抽象,并假设它们将在其初始范围之外使用。
  • SSA 和区域(region)

    • SSA形式 是编译器 IR 中广泛使用的表示形式。它提供了许多优点,包括使数据流分析变得简单和稀疏,因其与连续传递风格的关系而被编译器社区广泛理解,并在主要框架中建立。因此,IR 强制执行 SSA 的基于值的语义、其引用透明度和算法效率,所有这些都被认为对于现代编译器基础设施至关重要。然而,虽然许多现有的 IR 使用平坦的线性化 CFG,但表示更高级别的抽象推动将嵌套区域引入为 IR 中的一流概念。这超越了传统的区域形成,提升了更高级别的抽象(例如循环树),加速了编译过程或提取指令,或 SIMD 并行性 [4]、[5]、[6]。为了支持异构编译,系统必须支持结构化控制流、并发构造、源语言中的闭包的表达以及许多其他目的。一项具体的挑战是在嵌套区域上进行基于 CFG 的分析和转换。
    • 在此过程中,我们是内置牺牲了LLVM 的正规化( normalization )甚至规范化( canonicalization )特性。可以将复杂的数据结构和控制结构翻译(lowering)成一个小的正规化的集合是控制编译器复杂的关键。。具有pre-header, header,latch,body的规范循环结构是前端语言中各种循环结构的线性化控制流表示的原型案例。我们的目标是为用户提供一种选择:根据感兴趣的编译算法、编译流程中的传递,嵌套循环可以捕获为嵌套区域或线性化控制流。通过提供这样的选择,我们摆脱了 LLVM 的仅规范化方向,同时保留了在重要时处理更高级别抽象的能力。反过来,利用这些选择会引发有关如何控制抽象规范化的问题,这就是下一段的目的。
  • 渐进式的翻译(lowering)渐进性]:

    • 系统需要保留分析或优化性能所需的信息和结构。一旦降低抽象语义,尝试恢复抽象语义是脆弱的,并且在低级别硬塞这些信息通常是侵入性的(例如,在使用调试信息来记录结构的情况下,需要重新访问所有通道)。相反,系统应该保持计算结构并逐渐降低到硬件抽象。然后,结构的丢失是有意识的,并且仅在不再需要结构来匹配底层执行模型的情况下发生。例如,系统应在相关转换过程中保留结构化控制流,例如循环结构;删除这个结构,即降低到 CFG (Control Flow Graphs (CFGs))本质上意味着不会执行利用该结构的进一步转换。在生产编译器中对并行计算结构进行建模的最新技术突显了该任务通常是多么困难 [7]、[8]。

    • 作为推论,在同一 IR 中混合不同的抽象级别和不同的概念是允许一部分表示保留在较高级别的抽象中而另一部分则降低的关键。例如,这将使自定义加速器的编译器能够重用系统定义的一些高级结构和抽象以及特定于加速器的原始标量/向量指令。

    • 另一个推论是系统应该支持逐步降低,从较高级别的表示到最低级别,沿着多个抽象以小步骤执行。对多个抽象级别的需求源于编译器基础设施必须支持的各种平台和编程模型。

      以前的编译器已经在其管道中引入了多个固定的抽象级别,例如Open64 WHIRL 表示形式 [9] 有五个级别,Clang 编译器也是如此,它从 AST 降低到 LLVM IR、SelectionDAG、MachineInstr 和 MCInst。需要更灵活的设计来支持可扩展性。这对变换的相序具有深远的影响。随着编译器专家开始实现越来越多的转换过程,这些过程之间的复杂交互开始出现。早期的研究表明,组合优化过程可以让编译器发现有关程序的更多事实。组合传递的好处的第一个例子是混合常量传播、值编号和无法访问的代码消除[10]。

  • 声明和验证[简洁性和可追溯性]

    • 定义表示修饰符应该像引入新的抽象一样简单;编译器基础设施的好坏取决于它支持的转换。常见的转换应该可以实现为以机器可分析的格式以声明方式表达的重写规则,以推理重写的属性,例如复杂性和完成度。重写系统因其健全性和效率而被广泛研究,并应用于从类型系统到指令选择的众多编译问题。由于我们的目标是前所未有的可扩展性和增量降低功能,因此这为将程序转换建模为重写系统开辟了多种途径。它还提出了一些有趣的问题,例如如何表示重写规则和策略,以及如何构建能够通过多个抽象级别引导重写策略的机器描述。系统需要解决这些问题,同时保持可扩展性并强制执行单调和可再现的行为。
    • 生态系统的开放性还需要广泛的验证机制。虽然验证和测试对于检测编译器错误和捕获 IR 不变量很有用,但需要强大的验证方法和工具在可扩展的系统中得到了增强。该机制的目标应该是使其易于定义,并尽可能具有声明性,并提供单一的事实来源。长期目标是重现翻译验证 [11]、[12]、[13]、[14] 和现代编译器测试方法 [15] 的成功。两者目前都是可扩展编译器上下文中未解决的问题。
  • 源位置跟踪[可追溯性]:

    • 操作的详细信息(包括其原始位置和应用的转换)应该可以在系统内轻松追踪。这样做的目的是解决复杂编译系统中常见的缺乏透明度的问题,在这种情况下,几乎不可能理解最终表示是如何从原始表示构建的。

      在编译安全关键和敏感应用程序时,这尤其成问题,其中跟踪降低和优化步骤是软件认证程序的重要组成部分[16]。当对安全代码(例如对隐私敏感数据进行操作的加密协议或算法)进行操作时,编译器经常面临看似冗余或繁琐的计算,这些计算嵌入了源程序的功能语义未完全捕获的安全或隐私属性:此代码可能会阻止暴露侧通道或强化代码以抵御网络或故障攻击。优化可能会改变或完全无效此类保护[17];这种缺乏透明度在安全编译中被称为 WYSINWYX [18]。将高级信息准确传播到较低级别的一个间接目标是帮助支持安全且可追踪的编译。

3. IR 设计

MLIR 具有通用文本表示,支持 MLIR 的可扩展性并充分反映内存中表示,这对于可追溯性、手动 IR 验证和测试至关重要。可扩展性带来了冗长的负担,这可以通过 MLIR 支持的自定义语法来补偿;例如,图 7 说明了图 3 的用户定义语法。

image-20240625215406775

Operations: MLIR中的语义单位是“操作”,简称Op。在这个系统中,从“指令”到“函数”再到“模块”的所有内容都被建模为 Ops。 MLIR 没有固定的操作集,但根据简约和“一切可定制”原则,允许(并鼓励)用户定义的扩展。该基础设施提供了用于定义基于 TableGen [19] 的 Ops 的声明性语法,如图 5 所示。

image-20240625220230915

Ops(参见图 4)有一个唯一的操作码,一个标识操作及其方言的字符串。操作获取并产生零个或多个值,分别称为操作数和结果,并且这些值以 SSA 形式维护。值代表运行时的数据,

image-20240625220215582

总体的论文看下来,但从字面意思,从工程师的角度,还是很难理解MLIR设计的玄妙之处的.
我还是需要从官方的dmeo里面,来感受这些设计的奇妙之处.
这一部分另写一篇文章来介绍. MLIR的TOY语言-学习笔记

在这里插入图片描述

目前AI开源编译器都有哪些项目?

项目名称简介GitHub地址创始时间
TVMTVM是一个开源的机器学习编译器框架,用于从深度学习模型生成高效代码。它支持多种硬件后端,包括CPU、GPU和专用AI加速器。apache/tvm2017-12-31
XLAXLA是TensorFlow的编译器,用于优化和加速TensorFlow计算。tensorflow/tensorflow2016-11-30
GlowGlow是由Facebook AI Research开发的深度学习模型编译器,支持多种硬件后端。它旨在通过编译和优化深度学习图来提升推理性能。pytorch/glow2018-05-30
MLIRMLIR是一个通用的编译器基础设施,最初由Google开发,用于支持和优化不同的AI框架和硬件目标。MLIR提供了灵活的中间表示和转换机制。llvm/llvm-project2019-04-05
NGraphNGraph是由Intel开发的深度学习编译器和运行时环境,支持多种AI框架和硬件平台。它旨在提高深度学习模型的性能和可移植性。tensorflow/ngraph2017-10-15
ONNX RuntimeONNX Runtime是一个高性能的推理引擎,支持ONNX(开放神经网络交换)模型格式。它旨在通过优化和硬件加速提升模型的推理速度。microsoft/onnxruntime2018-12-04
Tensor ComprehensionsTensor Comprehensions是一个开源的编译器框架,旨在简化和优化深度学习模型的描述和执行。它允许用户用简洁的语法定义张量运算,并自动生成高效代码。facebookresearch/TensorComprehensions2018-02-22

参考

知乎- MLIR论文翻译

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

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

相关文章

02互联网行业的产品方向(2)

数字与策略产品 大数据时代,数据的价值越来越重要。大多数公司开始对内外全部数据进行管理与挖掘,将业务数据化,数据资产化,资产业务化,将数据产品赋能业务,通过数据驱动公司业务发展,支撑公司战…

Unity VR开发入门:探索虚拟现实世界的无限可能

目录 引言 Unity VR开发基础 1. 安装Unity与VR SDK 2. 创建VR项目 3. 理解VR场景结构 Unity VR开发实战 1. 场景搭建 2. 交互设计 创建C#脚本 编写VRInteractor脚本 应用脚本到场景 注意 修改VRInteractor脚本 3. 用户体验优化 4. 测试与调试 引言 随着科技的飞速…

docker: No space left on device处理与迁移目录

简介:工作中当遇到Docker容器内部的磁盘空间已满。可能的原因包括日志文件过大、临时文件过多或者是Docker容器的存储卷已满,需要我们及时清理相关文件,并对docker的路径进行迁移。 历史攻略: centos:清理磁盘空间 …

记录些MySQL题集(17)

一、MySQL索引为何使用B树结构? MySQL的索引机制中,默认使用BTree作为底层的数据结构,但为什么要选择B树呢?有人会说树结构是以二分法查找数据,所以会在很大程度上提升检索性能,这点确实没错,但…

C++初学者指南-5.标准库(第一部分)--标准库查询存在算法

C初学者指南-5.标准库(第一部分)–标准库查询存在算法 文章目录 C初学者指南-5.标准库(第一部分)--标准库查询存在算法any_of / all_of / none_ofcountcount_if相关内容 不熟悉 C 的标准库算法? ⇒ 简介 any_of / all_of / none_of 如果在输入范围(所有元素…

解决django与sqlite3不兼容报SQLite 3.9.0 or later is required错的问题

今天在尝试用pytest进行django的单元测试,pytest用的数据库是sqlite3,在window环境下测试得好好的,但是放到linux环境下就报错,具体是报django.core.exceptions.ImproperlyConfigured: SQLite 3.9.0 or later is required (found …

GPT-LLM

本心、输入输出、结果 文章目录 GPT-LLM前言国际公司AI发展概览国内公司AI发展概览GPT-LLM 编辑 | 简简单单 Online zuozuo 地址 | https://blog.csdn.net/qq_15071263 如果觉得本文对你有帮助,欢迎点赞、收藏、评论 前言 国际公司AI发展概览 公司主要AI贡献与产品特点OpenAI…

【LeetCode】day17:654 - 最大二叉树, 617 - 合并二叉树, 700 - 二叉树搜索树中的搜索, 98 - 验证二叉搜索树

LeetCode 代码随想录跟练 Day17 654.最大二叉树617.合并二叉树700.二叉搜索树中的搜索98.验证二叉搜索树 654.最大二叉树 题目描述: 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点,其值为 nums 中的…

SpringBoot整合SSE,实现后端主动推送DEMO

前言 说起服务端主动推送,大家第一个想到的一定是WEBSOCKET 。 作为软件工程师,不能无脑使用一种技术,要结合实际情况,择优选取。 SSE(Server-Sent Events)相比于WEBSOCKET 1、轻量化、兼容性 基于传统…

pytorch学习(十二)c++调用minist训练的onnx模型

在实际使用过程中,使用python速度不够快,并且不太好嵌入到c程序中,因此可以把pytorch训练的模型转成onnx模型,然后使用opencv进行调用。 所需要用到的库有: opencv 1.完整的程序如下 import torch from torch impo…

零基础STM32单片机编程入门(十七)SPI总线详解及RC522-NFC刷卡模块实战含源码

文章目录 一.概要二.SPI总线基本概念1.SPI总线内部框图2.总体特征3.通讯时序 三.RC522介绍1.NFC基本介绍2.RC522模块基本特点3.RC522模块原理图4.RC522模块SPI通讯时序 四.RC522模块读卡实验五.CubeMX工程源代码下载六.小结 一.概要 SPI总线是由Motorola公司提出,是…

05_解封装和解码

1. 基本概念 容器就是一种文件格式,比如flv、mkv、mp4等。包含下面5种流以及文件头信息。 流是一种视频数据信息的传输方式,5种流:音频,视频,字幕,附件,数据。 包在ffmpeg中代表已经编码好的一…

FPGA实验3:D触发器设计

一、实验目的及要求 熟悉Quartus II 的 VHDL 文本设计简单时序电路的方法; 掌握时序电路的描述方法、波形仿真和测试,特别是时钟信号的特性。 二、实验原理 运用Quartus II 集成环境下的VHDL文本设计方法设计简单时序电路——D触发器,依据…

三相PWM整流器滞环电流控制仿真matlab simulink

1、内容简介 略 88-可以交流、咨询、答疑 2、内容说明 略 三相PWM整流器已广泛应用工业与电气控制领域电流控制技术决定着三相PWM整流器系统的控制性能。综合比 较了各种电流控制方法应用较多的滞环比较…

C++ 类和对象 构造函数(下)

一 初始化列表: 1.1 构造函数体赋值: 在C中,构造函数用于创建对象并赋予其初始值。通常,我们可以在构造函数体内对成员变量进行赋值: class Date { public:Date(int year, int month, int day) {_year year;_mont…

golang 解压带密码的zip包

目录 Zip文件详解ZIP 文件格式主要特性常用算法Zip格式结构图总览Zip文件结构详解数据区本地文件头文件数据文件描述 中央目录记录区(核心目录记录区 )中央目录记录尾部区 压缩包解压过程方式1 通过解析中央目录区来解压方式2 通过读取本地文件头来解压两…

[言简意赅] Matlab生成FPGA端rom初始化文件.coe

🎎Matlab生成FPGA端rom初始化文件.coe 本文主打言简意赅。 函数源码 function gencoeInitialROM(width, depth, signal, filepath)% gencoeInitialROM - 生成 Xilinx ROM 初始化格式的 COE 文件%% 输入参数:% width - ROM 数据位宽% depth - ROM 数据深度% s…

heic文件怎么转换成jpg?上百份文件转换3秒就能搞定(办公必备)

heic和jpg是两种不同的图片格式,平时整理图片素材时,如果需要将heic转为jpg格式,那么可以使用相关的heic图片转换工具。 ​ 为什么要将heic文件转换成jpg?虽然HEIC格式具有很多优点,但是目前并不是所有设备和应用程序…

好玩模拟游戏推荐:缺氧:眼冒金星 单机游戏分享

《缺氧》 是一款太空殖民模拟游戏。 在外太空岩深处,你手下的勤劳开拓者们需要熟练掌握科技,战胜新的陌生生命形式,以及利用难以置信的太空技术来生存。甚至,还有可能繁荣起来。 建立广阔的基地以及探索生存所需的资源&#xff1…

服务攻防_01数据库安全RedisCouchdbH2database

一、数据库-Redis-未授权RCE&CVE 1、未授权访问:CNVD-2015-07557 (1)漏洞描述 Redis默认情况下会绑定在6379端口 如果没有采取相关策略(如添加防火墙规则阻止非信任来源IP访问),会将Redis暴露在公网…