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

ARM(5)内存管理单元MMU

一、虚拟地址和物理地址

    首先,计算机系统的内存被组成一个由M个连续的字节大小组成的数组。每字节都会有一个唯一的物理地址。CPU访问内存最简单的方式就是使用物理地址。如下图:

图 1 物理地址,物理寻址

    而现在都是采用的都是虚拟寻址的方法。CPU生成一个虚拟地址(VA),然后MMU(Memory Management Unit 内存管理单元) 将虚拟地址翻译成实际的物理地址,然后再进行物理寻址。

图2虚拟寻址

设想以下问题

1. 假如内存不足会怎么样?(对于一台32位系统来说,可以使用的内存有:2^32 bytes = 4GB);内存不足,超出内存空间会导致崩溃(crash)(例如32位系统,只有1GB RAM)

2. 内存碎片化:如果连续分配内存,程序可能找不到合适的空间(run out of space),即使有空间,但是不连续。

3. 多个程序指向相同的地址:不同程序间读写相同的内容,导致数据污染或崩溃

    怎么解决?让每一个程序拥有自己的虚拟内存空间。把程序的内存空间映射到物理内存(物理内存不足时把暂时不用的替换到硬盘上)。

  • 虚拟内存

虚拟内存是一种计算机系统的内存管理技术,它允许程序使用比实际物理内存更大的内存空间。

    在虚拟内存系统中,每个进程被分配了一个连续的虚拟地址空间,它通常比实际的物理内存大小要大得多。虚拟地址空间被划分为多个固定大小的单元,称为页面(pages)或虚拟页(virtual pages)。相应地,物理内存也被划分为与虚拟页大小相匹配的页面帧(page frames)。

    当程序访问虚拟内存中的某个地址时,操作系统通过地址映射机制将虚拟地址转换为物理地址。这个映射过程涉及将虚拟页从磁盘上的页面文件(page file)中加载到物理内存中的一个页面帧中。这样,虚拟内存可以提供比实际物理内存更大的可用内存空间。

    虚拟内存的主要优势是它允许在内存不足的情况下运行更大的程序或处理更大的数据集。它还提供了更好的内存管理保护机制,使不同的进程能够相互隔离和保护彼此的内存空间。

    虚拟内存本身不直接占用物理空间。虚拟内存是一种内存管理技术,它通过将部分数据存储在磁盘上的页面文件中,以释放物理内存并提供更大的可用内存空间。因此,虚拟内存的数据被分为两部分:存储在物理内存中的活动数据和存储在磁盘中的交换数据。

总而言之,虚拟内存是一种将物理内存和磁盘空间结合使用的内存管理技术,它提供了比实际物理内存更大的内存空间,并通过页面映射机制实现虚拟地址到物理地址的转换。它是现代操作系统中的重要组成部分,为程序提供了更大的内存空间和更好的内存管理功能。

虚拟页可以分为三种状态:

  1. 未分配的:未分配的页没有任何数据。
  2. 缓存的:当前已在物理内存中的已分配页。
  3. 未缓存的:未缓存在物理内存的已分配页。

虚拟内存是怎么解决3个问题:

1.内存不足时:当向系统申请内存但内存不足时,系统会把根据置换算法把暂进不用的内存置换到硬盘里,更新映射关系到硬盘上,再更新新申请的内存映射关系,让我们产生无限内存的错觉。(交换到硬盘后会导致性能下降,硬盘读取速度比内存慢太多了)。例如下面这个例子,程序0,1,2分别加载了物理地址的0,1,2。此时程序3进来,也需要申请内存。然后就根据算法先把内存腾出来,腾出来的放到磁盘上,再把腾出来的空间给程序3。这样就可以解决内存不足的问题而不会导致崩溃。

2.内存碎片:程序通过自身的映射表可以随意找到合适的物理内存,而不一定需要连续分配。

3.程序间相同的地址:

即使程序的地址相同,但是每个程序通过自己的映射表映射到不同的物理内存而不会互相产生干扰。但是程序间相互独立一定是好的吗?并不是,因为有些内存是需要共享的。例如不同的程序会共享系统文件,系统选择框等。让程序间实现共享内存的方法是把地址指向相同的物理内存。

内存映射主要由操作系统的内存管理单元(Memory Management Unit, MMU)管理操作的,一切都是同它来掌控。

程序访问内存的步骤:地址翻译      

1. 程序指定加载一个逻辑地址

2. 计算机通过映射把逻辑地址转换成物理地址

3. 如果物理地址不在内存中,操作系统会把它从硬盘中加载到内存里,更新映射关系(原来是指向disk的,现在指向内存)

4. 计算机通过物理地址把内存内容读取出来并且返回给程序

2.1 为什么需要虚拟地址

虚拟地址的引入主要是为了满足以下几个需求和提供相应的优势:

    1. 内存隔离:每个进程都拥有自己独立的虚拟地址空间,使得进程之间的内存彼此隔离。这样,一个进程无法直接访问另一个进程的内存,提高了系统的安全性和稳定性。

    2. 大内存支持:虚拟地址空间可以比实际的物理内存空间大得多。这使得操作系统能够支持大容量的内存需求,可以运行更大的应用程序和处理更多的数据。

    3. 内存管理灵活性:虚拟地址空间的使用可以动态地进行管理。操作系统可以根据需要将虚拟地址映射到物理内存或其他存储设备上,实现内存的灵活分配和回收,包括页面置换、页面回写和内存映射文件等技术。

    4. 虚拟内存映射:虚拟地址与物理地址之间的映射关系可以通过页表等数据结构来实现。这使得操作系统能够将虚拟地址转换为物理地址,从而实现对内存的透明访问。

    5. 内存保护:虚拟地址空间允许操作系统对内存区域进行权限控制和访问限制。通过设置页面级别的访问权限和保护位,操作系统可以防止非法访问和保护系统关键数据和代码。

     总之,虚拟地址的引入使得操作系统能够提供更大的地址空间、更好的内存隔离、灵活的内存管理和保护机制。它为多进程环境下的程序提供了一种抽象层,使得程序可以使用独立且安全的地址空间,同时有效利用系统的资源。

  1. 物理地址PA:物理地址是计算机内存中实际的硬件地址。它是由计算机系统中的内存管理单元(MMU)转换而来,用于直接访问主存储器中的数据。物理地址是一个唯一的标识符,用于定位内存中的特定字节或字。
  2. 虚拟地址VA:虚拟地址是一种抽象的地址,由进程或程序使用。它是在虚拟内存系统中使用的地址,与物理地址相对应。虚拟地址空间被划分为不同的页(或页框),并通过地址转换机制映射到物理内存中的相应页框。虚拟地址提供了一种独立于实际物理内存布局的方式来访问内存,使得每个进程都有自己独立的地址空间。

     那么虚拟地址是怎么转化成物理地址的呢?这就涉及到虚拟内存,页表等等新东西,接下来看。

三、页Page/页表/页表项(PTE)

MMU是负责把虚拟地址映射为物理地址,但凡"映射"都要解决两个问题:映射的最小单位(粒度)和映射的规则。

     页(Page):MMU中VA到PA映射的最小单位称为页(Page),映射的最低粒度是单个虚拟页到物理页,页大小通常是4K,即一次最少要把4K大小的VA页块整体映射到4K的PA页块(从0开始4K对齐划分页块),页内偏移不变(低12bit),用于索引4K空间的页。

      页表(Page Table),就是一个个页表条目PTE(Page Table Entry)组成的数组,每一条称为一个页表条目(Page Table Entry,即PTE)。

  MMU软件配置的核心是页表(Page Table),它描述MMU的映射规则,即虚拟内存哪(几)个页映射到物理内存哪(几)个页帧。整个页表保存在片外内存,MMU通过查找页表确定一个VA应该映射到什么PA,以及是否有权限映射。

    映射规则如下图:

    例:如VA的一页0x30004000~0x30004fff被映射到PA的一页 0x00008000~0x00008fff,当CPU执行单元访问虚拟地址0x30004008,实际访问的物理地址是0x00008008(0x30004008和0x00008008分别位于虚实两套地址空间,互不相干,不存在重叠和冲突)。以页为最小单位,就是不能把VA中某一页划分成几小块分别映射到不同PA,也不能把VA中属于不同页的碎块映射到PA某一页的不同部分,必须页对页(4K大小)整体映射。

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

Q:页表为什么保存在主存中?

A:页表保存在片外内存的主要原因是空间的限制和灵活性的需求。

1. 空间限制:页表可能非常庞大(32bit:1 billion PTE!),特别是在具有大型虚拟地址空间的系统中。将整个页表保存在处理器的寄存器或缓存中是不切实际的,因为这些存储器有限的容量无法容纳如此大的页表。片外内存(主存)提供了更大的存储容量,可以容纳大型的页表结构。

2. 灵活性:页表的大小和结构可能随着进程的需要而变化。将页表保存在片外内存中可以更容易地进行动态调整和管理。当页表需要扩展或收缩时,可以通过修改指向页表的指针或重新分配内存来实现,而不需要对处理器的硬件结构进行改动。

3. 虚拟化支持:在虚拟化环境中,多个虚拟机可能同时运行在同一台物理机上。每个虚拟机都有自己的独立虚拟地址空间和页表。通过将页表保存在片外内存中,不同的虚拟机可以独立管理和访问自己的页表,增加了虚拟化的灵活性和隔离性。

    虽然将页表保存在片外内存中增加了访问开销(因为需要额外的内存访问),但这种折衷是为了满足大型地址空间和动态的内存管理需求。同时,使用高速缓存(如TLB)来缓存最近使用的页表项可以在一定程度上减少访问延迟。

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

四、虚拟地址和页表条目的关系

    在第3节中描述了通过页表条目找到物理内存中的页。那么接下来再来看看给定一个虚拟地址,怎么找到它对应的页表条目PTE。

    一个n位的虚拟地址包含两部分:一个p位的虚拟页面偏移(VPO)和一个(n-p)位的虚拟页号(VPN)。MMU正是利用了VPN来选择合适的PTE。然后将PTE中PPN和VPO串联起来,就得到了实际的物理地址。

图4-1 虚拟地址和PTE和物理地址

    至此,来简要理一下简要流程。

1.CPU生成一个虚拟地址,并把它传给MMU。

2.MMU生成PTE地址,请求高速内存/内存返回实际数据。

3.内存向MMU返回PTE。

4.MMU按照图4-1逻辑,构建物理地址PA,并请求内存

5.主存返回物理地址存储的数据


五、TLB (Translation Lookaside Buffers)

 但如果MMU每次地址转换都到位于外部内存的页表上查找PTE,转换速度就会大大降低,内存的速度需要几百个CPU周期。为了减少这个开销,于是出现了TLB (Translation Lookaside Buffers)即转换快表,又简称快表,可以理解为MMU内部专用的存放页表的cache,保存着最近使用的PTE乃至全部页表。

    MMU接收到虚拟地址后,首先在TLB中查找,如果找到该VA对应的PTE就直接转换,找不到再去外存页表查找,并置换进TLB。TLB属于片上SRAM,访问速度快,通过TLB缓存PTE可以节省MMU访问外存页表的时间,从而加速虚实地址转换。TLB和CPU cache的工作原理一样,只是TLB专用于为MMU缓存页表。

    带有TLB的虚拟地址转化过程如图5-1所示。在TLB不命中的时候,从内存中返回的PTE会被缓存在TLB中,可能会覆盖一个已存在的条目。

六、多级页表

    

    Q:为什么要采取这种多级页表的形式?

    A:省内存空间。

    多级页表相较于单级页表可以节省空间的主要原因是多级页表采用了分层的结构,使得整个页表不需要一次性加载到内存中(如上图中的2^36个PTE)。这样,在实际使用中,只需要加载当前进程所使用的部分页表(4*2^9个PTE)从而减少了内存的占用。

    采用多级页表的主要原因有以下几点:

    1. 空间效率:多级页表可以根据需要动态分配和释放内存空间。相比于单级页表,多级页表可以节省大量的内存空间。在单级页表中,每个虚拟页都需要一个对应的页表项,而多级页表可以根据需要只分配实际使用的页表项,减少了内存开销。

    2. 快速访问:多级页表可以提高地址转换的速度。在大型内存空间中,使用单级页表需要遍历整个页表来进行地址映射,这会导致访问速度变慢。而多级页表通过分层的结构,可以将大型页表划分为多个小的页表,每次只需要查找相应的页表,从而加快了地址转换的速度。

    3. 灵活性:多级页表提供了更大的灵活性和可扩展性。通过增加额外的级别,可以处理更大的内存空间。同时,多级页表可以根据实际需求进行调整和优化,以适应不同的应用程序和系统环境。

    总的来说,采用多级页表可以提高内存管理的效率和灵活性,减少内存开销,并提高地址转换的速度。这使得操作系统能够更好地管理大型内存空间和处理复杂的内存访问需求。

七、MMU映射失败的几种情况

    1.访问了受内核保护的页面,或者访问了只读的页面,此时内核会抛出段错误。

    2.VP和PP没有产生映射关系,但是数据页已经被其他进程加载到内存中了,此时只需要建立VP和PP的映射关系,称为次级缺页中断。

    3.VP和PP没有产生映射关系,数据页也没有被加载到内存中(在磁盘上),此时需要发生磁盘io从磁盘中加载页到内存中,还需要建立VP和PP的映射关系,称为严重缺页中断。

    除了第一点,第二第三都会以内核降低自身运行速度来修复,也就是通过中断形成页表映射,然后再重新执行引起中断的命令(此时已经更新了物理内存和PTE,数据页已经在内存中并且建立映射关系了)。

如果物理页不在内存中,CPU生成一个缺页异常(page fault exception):

     1. CPU跳转到系统缺页处做清除置换

     2. 系统选择某一页从内存中移除并写入硬盘中(这里涉及页面转换算法,如最优算法、先进先出算法、最近最久未使用算法、时钟算法、最不常用算法)

     3. 如果被选中从内存中移除的页面是脏数据,必须把它先写到硬盘上

     4. 从硬盘中读取缺页异常的页面并写到内存中

     5. 更新页表的映射关系

     6. 系统跳转回到引起缺页异常的指令处

参考链接:

Virtual Memory: 14 Summary (youtube.com) (合集1-14)

【MMU篇】一文总结ARMv8中的MMU架构_armv8 mmu-CSDN博客

https://zhuanlan.zhihu.com/p/484183354

相关文章:

ARM(5)内存管理单元MMU

一、虚拟地址和物理地址 首先,计算机系统的内存被组成一个由M个连续的字节大小组成的数组。每字节都会有一个唯一的物理地址。CPU访问内存最简单的方式就是使用物理地址。如下图: 图 1 物理地址,物理寻址 而现在都是采用的都是虚拟寻址的方法。CPU生成一…...

文件上传漏洞原理

原理:\n应用中存在上传功能,但是上传的文件没有经过严格的合法性检验或者检验函数存在缺陷,导致可以上传木马文件到服务器,并且能够执行其中的恶意代码。\n\n危害:\n服务器的网页篡改,网站被挂马&#xff0…...

Web安全 - 安全防御工具和体系构建

文章目录 安全标准和框架1. 国内安全标准:等级保护制度(等保)2. 国际安全标准:ISO27000系列3. NIST安全框架:IDPRR方法4. COBIT与ITIL框架 防火墙防火墙的基本作用防火墙的三种主要类型防火墙的防护能力防火墙的盲区 W…...

服务器数据恢复—raid磁盘故障导致数据库文件损坏的数据恢复案例

服务器存储数据恢复环境&故障: 存储中有一组由3块SAS硬盘组建的raid。上层win server操作系统层面划分了3个分区,数据库存放在D分区,备份存放在E分区。 RAID中一块硬盘的指示灯亮红色,D分区无法识别;E分区可识别&a…...

requests 中data=xxx、json=xxx、params=xxx 分别什么时候用

如果是要做爬虫模拟一个页面提交,看原页面是post还是get,以及Content-Type是什么。 GET 请求 使用 paramsxxx,查询参数会被编码到 URL 中。POST 请求,Content-Type为 application/x-www-form-urlencoded的,使用 dataxx…...

毕设 大数据抖音短视频数据分析与可视化(源码)

文章目录 0 前言1 课题背景2 数据清洗3 数据可视化地区-用户观看时间分界线每周观看观看路径发布地点视频时长整体点赞、完播 4 进阶分析相关性分析留存率 5 深度分析客户价值判断 0 前言 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕…...

【SQL】深入理解SQL:从基础概念到常用命令

目录 1. SQL基础概念1.1 数据库与表1.2 行与列1.3 数据库与表结构示意图 2. 常用SQL命令3. DML 命令3.1 SELECT语句3.2 INSERT语句3.3 UPDATE语句3.4 DELETE语句 4. DDL 命令3.4.1 CREATE 命令3.4.2 ALTER 命令3.4.3 DROP 命令 5. DCL 命令3.6.1 GRANT 命令3.6.2 REVOKE 命令 学…...

一文看懂计算机中的大小端(Endianess)

文章目录 前言一、什么是大小端二、如何判断大小端三、大小端的转换3.1 使用标准库函数3.2 手动实现大小端转换 前言 本文主要探讨计算机中大小端的相关概念以及如何进行大小端的判断和转换等。 一、什么是大小端 大小端(Endianess)是指计算机系统在存…...

如何给父母安排体检?

总结:给父母安排体检,常规项目针对项目。 其中针对项目是根据父母自身的病史来设计。 如何快速了解这些体检项目?我自己认为最快的方式,自己去医院体检两次,这样对体检的项目有一定的了解,比如这个项目怎么…...

C++之模版进阶篇

目录 前言 1.非类型模版参数 2.模版的特化 2.1概念 2.2函数模版特化 2.3 类模板特化 2.3.1 全特化和偏特化 2.3.2类模版特化应用实例 3.模版分离编译 3.1 什么是分离编译 3.2 模板的分离编译 3.3 解决方法 4. 模板总结 结束语 前言 在模版初阶我们学习了函数模版和类…...

Vue3 中的 `replace` 属性:优化路由导航的利器

嘿,小伙伴们!今天给大家带来一个Vue3中非常实用的小技巧——replace属性的使用方法。在Vue Router中,replace属性可以帮助我们在导航时不留下历史记录,这对于一些特定的应用场景非常有用。话不多说,让我们直接进入实战…...

vite学习教程06、vite.config.js配置

前言 博主介绍:✌目前全网粉丝3W,csdn博客专家、Java领域优质创作者,博客之星、阿里云平台优质作者、专注于Java后端技术领域。 涵盖技术内容:Java后端、大数据、算法、分布式微服务、中间件、前端、运维等。 博主所有博客文件…...

【大数据】Flink CDC 实时同步mysql数据

目录 一、前言 二、Flink CDC介绍 2.1 什么是Flink CDC 2.2 Flink CDC 特点 2.3 Flink CDC 核心工作原理 2.4 Flink CDC 使用场景 三、常用的数据同步方案对比 3.1 数据同步概述 3.1.1 数据同步来源 3.2 常用的数据同步方案汇总 3.3 为什么推荐Flink CDC 3.4 Flink …...

JavaEE: 深入解析HTTP协议的奥秘(1)

文章目录 HTTPHTTP 是什么HTTP 协议抓包fiddle 用法 HTTP 请求响应基本格式 HTTP HTTP 是什么 HTTP 全称为"超文本传输协议". HTTP不仅仅能传输文本,还能传输图片,传输音频文件,传输其他的各种数据. 因此它广泛应用在日常开发的各种场景中. HTTP 往往是基于传输层的…...

OpenStack Yoga版安装笔记(十六)Openstack网络理解

0、前言 本文将以Openstack在Linux Bridge环境下的应用为例进行阐述。 1、Openstack抽象网络 OpenStack的抽象网络主要包括网络(network)、子网(subnet)、端口(port),路由器(rout…...

PEFT库和transformers库在NLP大模型中的使用和常用方法详解

PEFT(Parameter-Efficient Fine-Tuning)库是一个用于有效微调大型预训练语言模型的工具,尤其是在计算资源有限的情况下。它提供了一系列技术,旨在提高微调过程的效率和灵活性。以下是PEFT库的详细解读以及一些常用方法的总结&…...

静止坐标系和旋转坐标系变换的线性化,锁相环线性化通用推导

将笛卡尔坐标系的电压 [ U x , U y ] [U_x, U_y] [Ux​,Uy​] 通过旋转变换(由锁相环角度 θ P L L \theta_{PLL} θPLL​ 控制)转换为 dq 坐标系下的电压 [ U d , U q ] [U_d, U_q] [Ud​,Uq​]。这个公式是非线性的,因为它涉及到正弦和余弦函数。 图片中的推导过程主要…...

AI学习指南深度学习篇-学习率衰减的变体及扩展应用

AI学习指南深度学习篇 - 学习率衰减的变体及扩展应用 在深度学习的训练过程中,学习率的选择对模型的收敛速度和最终效果有重要影响。为了提升模型性能,学习率衰减(Learning Rate Decay)作为一种优化技术被广泛应用。本文将探讨多…...

成都睿明智科技有限公司真实可靠吗?

在这个日新月异的电商时代,抖音作为短视频与直播电商的佼佼者,正以前所未有的速度重塑着消费者的购物习惯。而在这片充满机遇与挑战的蓝海中,成都睿明智科技有限公司以其独到的眼光和专业的服务,成为了众多商家信赖的合作伙伴。今…...

力扣6~10题

题6(中等): 思路: 这个相较于前面只能是简单,个人认为,会print打印菱形都能搞这个,直接设置一个2阶数组就好了,只要注意位置变化就好了 python代码: def convert(self,…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...

蓝桥杯 冶炼金属

原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...