本公开的实施例涉及人工智能(ai)领域,具体涉及一种内存分配方法及设备。
背景技术
深度学习极大地促进了人工智能的发展,而目前深度模型的训练系统大多是基于数据流图计算的引擎,因此相关的优化就变得极为重要。数据流图的特点是数据节点几乎都是大型的张量,由于训练过程一般需要计算梯度,数据流图包含正向计算和求导两个过程,节点数量众多,因此内存的优化就极为重要。
技术实现要素:
本公开的实施例提供一种内存分配方法,包括:计算冲突请求间的相对内存位置关系;以及根据所述相对内存位置关系计算内存分配的最优解。
例如,在本公开实施例提供的内存分配方法中,所述冲突请求是在同一时间要求占用的内存地址有重叠的请求。
例如,在本公开实施例提供的内存分配方法中,所述计算冲突请求间的相对内存位置关系,包括:将每个所述请求转换为一个分配事件和一个释放事件,并按时间对所述每个分配事件和所述每个释放事件排序,并获取每个所述事件对应的内存大小;初始化当前已分配的内存块集合、当前空余内存块集合以及内存块相对关系链表;处理所述每个所述分配事件和每个所述释放事件;根据所述分配事件和所述释放事件的处理结果获取所述相对内存位置关系。
例如,在本公开实施例提供的内存分配方法中,所述初始化当前已分配的内存块集合、当前空余内存块集合以及内存块相对关系链表,包括:设置当前已分配的内存块集合为空集;设置当前空余内存块集合为空集;对于每个所述请求,设置所述内存块相对关系链表中内存块的起始地址比所述请求对应的内存块的起始地址低的第一个请求为空、内存块的起始地址比所述请求对应的内存块的起始地址高的第一个请求为空。
例如,在本公开实施例提供的内存分配方法中,所述处理所述每个分配事件和每个所述释放事件,包括:对于分配事件,如果所述当前空余内存块集合为空集,则在所述当前空余内存块集合中加入所述分配事件对应的内存大小的内存块到所述当前空余内存块集合中;如果所述当前空余内存块集合不为空集,在所述当前空余内存块集合中寻找不小于所述分配事件对应的内存大小的最小的一段连续内存块作为空闲内存块,如果不存在这样的内存块,将当前空余内存块集合中最大的内存块的大小修改为所述分配事件对应的内存大小并将其作为所述空闲内存块;将所述空闲内存块从所述当前空余内存块集合中移除,如果所述空闲内存块的大小大于所述分配事件对应的内存大小,则将所述空闲内存块的大小与所述分配事件对应的内存大小的差对应的内存块插入到所述当前空余内存块集合中;在当前已分配的内存块集合中查找起始地址小于所述空闲内存块的起始地址条件下具有最高起始地址的最高内存块,设置内存块的起始地址比所述请求对应的内存块的起始地址低的第一个请求对应于所述最高内存块,如果查找不到所述最高内存块,则设置内存块的起始地址比所述请求对应的内存块的起始地址低的第一个请求为空;在当前已分配的内存块集合中查找起始地址大于所述空闲内存块的起始地址条件下具有最低起始地址的最低内存块,设置内存块的起始地址比所述请求对应的内存块的起始地址高的第一个请求对应于所述最低内存块,如果查找不到所述最低内存块,则设置内存块的起始地址比所述请求对应的内存块的起始地址高的第一个请求为空;对于释放事件,将所述释放事件对应的内存块从所述当前已分配的内存集合中移除,并将所述释放事件对应的内存块加入所述当前空余内存块集合;如果所述当前空余内存块集合中存在与所述释放事件对应的内存块地址连续的内存块,则将其与所述释放事件对应的内存块合并。
例如,在本公开实施例提供的内存分配方法中,根据所述分配事件和所述释放事件的处理结果获取所述相对内存位置关系,包括:对于每个所述请求,初始化所述请求的对应的内存块的起始地址大于等于第一请求集合中每个请求对应的内存块的结束地址;将所述第一请求集合与内存块的起始地址比所述请求对应的内存块的起始地址低的第一个请求的集合的并集作为更新后的第一请求集合;将所述请求对应的内存块的最大结束地址小于等于内存块的起始地址比所述请求对应的内存块的起始地址高的第一个请求的集合与所述请求的集合的并集作为第二请求集合。
例如,在本公开实施例提供的内存分配方法中,根据所述相对内存位置关系计算最优解,包括:初始化每个所述请求对应的内存块的起始地址;对于每个所述请求,如果所述请求的对应的内存块的起始地址大于等于第一请求集合中每个请求对应的内存块的结束地址,则设置所述请求对应的内存块的起始地址为零;对于每个所述请求,如果存在所述请求的对应的内存块的起始地址小于所述第一请求集合中每个请求对应的内存块的结束地址,则对于所有的所述第一请求集合中的每个请求计算其对应的内存块的起始地址。
例如,在本公开实施例提供的内存分配方法中,对于所有的所述第一请求集合中的每个请求计算其对应的内存块的起始地址,包括:计算所有的所述第一请求集合中的每个请求对应的内存块的起始地址和长度之和作为所述请求的起始内存地址。
本公开的实施例还提供一种用于内存分配的设备,包括:一个或多个处理器;一个或多个存储器;以及存储在所述存储器中的计算机程序指令,在所述计算机程序指令被所述处理器运行时执行以下步骤:计算冲突请求间的相对内存位置关系;以及根据所述相对内存位置关系计算内存分配的最优解。
例如,在本公开实施例提供的用于内存分配的设备中,所述冲突请求是在同一时间要求占用的内存地址有重叠的请求。
例如,在本公开实施例提供的用于内存分配的设备中,所述计算冲突请求间的相对内存位置关系,包括:将每个所述请求转换为一个分配事件和一个释放事件,并按时间对所述每个分配事件和所述每个释放事件排序,并获取每个所述事件对应的内存大小;初始化当前已分配的内存块集合、当前空余内存块集合以及内存块相对关系链表;处理所述每个所述分配事件和每个所述释放事件;根据所述分配事件和所述释放事件的处理结果获取所述相对内存位置关系。
例如,在本公开实施例提供的用于内存分配的设备中,所述初始化当前已分配的内存块集合、当前空余内存块集合以及内存块相对关系链表,包括:设置当前已分配的内存块集合为空集;设置当前空余内存块集合为空集;对于每个所述请求,设置所述内存块相对关系链表中内存块的起始地址比所述请求对应的内存块的起始地址低的第一个请求为空、内存块的起始地址比所述请求对应的内存块的起始地址高的第一个请求为空。
例如,在本公开实施例提供的用于内存分配的设备中,所述处理所述每个分配事件和每个所述释放事件,包括:对于分配事件,如果所述当前空余内存块集合为空集,则在所述当前空余内存块集合中加入所述分配事件对应的内存大小的内存块到所述当前空余内存块集合中;如果所述当前空余内存块集合不为空集,在所述当前空余内存块集合中寻找不小于所述分配事件对应的内存大小的最小的一段连续内存块作为空闲内存块,如果不存在这样的内存块,将当前空余内存块集合中最大的内存块的大小修改为所述分配事件对应的内存大小并将其作为所述空闲内存块;将所述空闲内存块从所述当前空余内存块集合中移除,如果所述空闲内存块的大小大于所述分配事件对应的内存大小,则将所述空闲内存块的大小与所述分配事件对应的内存大小的差对应的内存块插入到所述当前空余内存块集合中;在当前已分配的内存块集合中查找起始地址小于所述空闲内存块的起始地址条件下具有最高起始地址的最高内存块,设置内存块的起始地址比所述请求对应的内存块的起始地址低的第一个请求对应于所述最高内存块,如果查找不到所述最高内存块,则设置内存块的起始地址比所述请求对应的内存块的起始地址低的第一个请求为空;在当前已分配的内存块集合中查找起始地址大于所述空闲内存块的起始地址条件下具有最低起始地址的最低内存块,设置内存块的起始地址比所述请求对应的内存块的起始地址高的第一个请求对应于所述最低内存块,如果查找不到所述最低内存块,则设置内存块的起始地址比所述请求对应的内存块的起始地址高的第一个请求为空;对于释放事件,将所述释放事件对应的内存块从所述当前已分配的内存集合中移除,并将所述释放事件对应的内存块加入所述当前空余内存块集合;如果所述当前空余内存块集合中存在与所述释放事件对应的内存块地址连续的内存块,则将其与所述释放事件对应的内存块合并。
例如,在本公开实施例提供的用于内存分配的设备中,根据所述分配事件和所述释放事件的处理结果获取所述相对内存位置关系,包括:对于每个所述请求,初始化所述请求的对应的内存块的起始地址大于等于第一请求集合中每个请求对应的内存块的结束地址;将所述第一请求集合与内存块的起始地址比所述请求对应的内存块的起始地址低的第一个请求的集合的并集作为更新后的第一请求集合;将所述请求对应的内存块的最大结束地址小于等于内存块的起始地址比所述请求对应的内存块的起始地址高的第一个请求的集合与所述请求的集合的并集作为第二请求集合。
例如,在本公开实施例提供的用于内存分配的设备中,根据所述相对内存位置关系计算最优解,包括:初始化每个所述请求对应的内存块的起始地址;对于每个所述请求,如果所述请求的对应的内存块的起始地址大于等于第一请求集合中每个请求对应的内存块的结束地址,则设置所述请求对应的内存块的起始地址为零;对于每个所述请求,如果存在所述请求的对应的内存块的起始地址小于所述第一请求集合中每个请求对应的内存块的结束地址,则对于所有的所述第一请求集合中的每个请求计算其对应的内存块的起始地址。
例如,在本公开实施例提供的用于内存分配的设备中,对于所有的所述第一请求集合中的每个请求计算其对应的内存块的起始地址,包括:计算所有的所述第一请求集合中的每个请求对应的内存块的起始地址和长度之和作为所述请求的起始内存地址。
本公开的实施例还提供一种用于内存分配的设备,包括:相对内存位置计算装置,被配置为计算冲突请求间的相对内存位置关系;以及内存分配最优解计算装置,被配置为根据所述相对内存位置关系计算内存分配的最优解。
例如,在本公开实施例提供的用于内存分配的设备中,所述相对内存位置计算装置包括:排序模块,被配置为将每个所述请求转换为一个分配事件和一个释放事件,并按时间对所述每个分配事件和所述每个释放事件排序,并获取每个所述事件对应的内存大小;第一初始化模块,被配置为初始化当前已分配的内存块集合、当前空余内存块集合以及内存块相对关系链表;处理模块,被配置为处理所述每个所述分配事件和每个所述释放事件;以及相对内存位置关系获取模块,被配置为根据所述分配事件和所述释放事件的处理结果获取所述相对内存位置关系。
例如,在本公开实施例提供的用于内存分配的设备中,所述内存分配最优解计算装置包括:第二初始化模块,被配置为初始化每个所述请求对应的内存块的起始地址;以及内存块起始地址计算模块,被配置为对于每个所述请求,如果所述请求的对应的内存块的起始地址大于等于第一请求集合中每个请求对应的内存块的结束地址,则设置所述请求对应的内存块的起始地址为零;对于每个所述请求,如果存在所述请求的对应的内存块的起始地址小于所述第一请求集合中每个请求对应的内存块的结束地址,则对于所有的所述第一请求集合中的每个请求计算其对应的内存块的起始地址。
例如,本公开实施例提供的内存分配方法和设备可以得到一个较优的内存分配方案,且分配方案的代价小、运行速度快。
附图说明
为了更清楚地说明本公开实施例的技术方案,下面将对实施例或相关技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅涉及本公开的一些实施例,并非对本公开的限制。
图1是本公开实施例提供的一种内存分配方法的流程图;
图2是本公开实施例提供的两个内存分配请求的示意图;
图3是本公开实施例提供的实现图1中步骤s100的方法的流程图;
图4是本公开实施例提供的实现图3中步骤s120的方法的流程图;
图5a和图5b是本公开实施例提供的实现图3中步骤s130的方法的流程图;
图6是本公开实施例提供的实现图3中步骤s140的方法的流程图;
图7是本公开实施例提供的实现图1中步骤s200的方法的流程图;
图8是本公开实施例提供的一种内存分配的设备的示意图之一;以及
图9是本公开实施例提供的一种内存分配的设备的示意图之二。
具体实施方式
下面将结合附图,对本公开实施例中的技术方案进行清楚、完整地描述参考在附图中示出并在以下描述中详述的非限制性示例实施例,更加全面地说明本公开的示例实施例和它们的多种特征及有利细节。应注意的是,图中示出的特征不是必须按照比例绘制。本公开省略了已知材料、组件和工艺技术的描述,从而不使本公开的示例实施例模糊。所给出的示例仅旨在有利于理解本公开示例实施例的实施,以及进一步使本领域技术人员能够实施示例实施例。因而,这些示例不应被理解为对本公开的实施例的范围的限制。
除非另外特别定义,本公开使用的技术术语或者科学术语应当为本公开所属领域内具有一般技能的人士所理解的通常意义。本公开中使用的“第一”、“第二”以及类似的词语并不表示任何顺序、数量或者重要性,而只是用来区分不同的组成部分。此外,在本公开各个实施例中,相同或类似的参考标号表示相同或类似的构件。
一种内存优化的方法是在数据流图上进行依赖分析,并模拟运行已有的动态内存分配算法,但这种方法并没有充分利用数据流图的全局静态信息,无法达到最优效果。又一种内存优化方法是利用复杂度更高的图着色类算法,但由于复杂度过高而无法处理大规模数据流图。
本公开的实施例提供一种内存分配方法,当给定一个数据流图拓扑排序后的计算序列以及各个数据节点所需的内存大小之后,按照本公开实施例提供的方法可以得到一个较优的内存分配方案。
例如,如果定义(实际内存用量/计算序列瓶颈处内存大小-1)作为分配方案的代价,则本公开实施例提供的方法的代价一般在0.1以内,大部分时候在0.01以内,比一般的动态分配方法代价小一半左右,而且运行速度快。
本公开的实施例提供一种内存分配方法,如图1所示,该方法包括如下步骤。
步骤s100:计算冲突请求间的相对内存位置关系;以及
步骤s200:根据相对内存位置关系计算内存分配的最优解。
例如,在本公开实施例提供的内存分配方法中,冲突请求是在同一时间要求占用的内存地址有重叠的请求。
例如,在本公开实施例提供的内存分配方法中,数据流图已经拓扑排序,例如n个内存分配请求可以表达为n个三元组:(s_i,t_i,z_i),其中,(s_i,t_i)分别是第i个请求的分配和释放时刻,z_i是其请求的内存大小,0≤i<n。对于每个请求i,其起始内存地址a_i,满足a_i≥0,而且对于任意时间冲突的请求i、j,空间不冲突;最终希望起始内存地址与请求的内存大小之和的最大值max{a_i+z_i}尽量小。
例如,在本公开中,对于两个请求i、j,如果二者在时间上有重合,则称为时间冲突,即s_i<t_j以及s_j<t_i;对于两个请求i、j,如果二者在空间(内存地址)上有重合,则称为空间冲突,即a_i<a_j+z_j以及a_j<a_i+z_i。例如,一个合理的分配方案要求所有时间冲突的请求没有空间冲突。
例如,图2是本公开实施例提供的两个内存分配请求的示意图,图2中的横坐标代表时间,纵坐标代表内存地址,图2中的两个方框代表两个内存分配请求,这两个内存分配请求有时间冲突但是没有空间冲突。例如,当两个分配请求既有时间冲突又有空间冲突时,在图2的坐标系中,两个方框将会有交叠区域(该情况图2中未示出)。
例如,在本公开中,内存地址是一个非负整数,内存地址从0开始。内存块是一段连续的内存,可以由其起始地址和长度来定义。
例如,内存优化的问题可以转化为对于时间冲突的请求i和j,决定i和j的相对内存位置关系的问题,使其没有空间冲突。在该关系确定后,根据相对内存位置关系计算内存分配的最优解。
例如,如图3所示,在本公开实施例提供的内存分配方法的示例中,计算冲突请求间的相对内存位置关系(即图1中的步骤s100)包括如下步骤。
步骤s110:将每个请求转换为一个分配事件和一个释放事件,按时间对每个分配事件和每个释放事件排序,并获取每个事件对应的内存大小;
步骤s120:初始化当前已分配的内存块集合、当前空余内存块集合以及内存块相对关系链表;
步骤s130:处理每个分配事件和每个释放事件;以及
步骤s140:根据分配事件和释放事件的处理结果获取相对内存位置关系。
例如,在步骤s110中,可以将n个请求转换成n个分配事件和n个释放事件,并按时间排序。每个请求会产生两个事件,一个分配事件和一个释放事件,一共有2n个事件。每个事件用一个二元组(e_j,m_j)来表示,其中,0≤j<2n,0≤m_j<n,m_j表示该事件所属的请求的编号,e_j表示该事件的类型,其取值为alloc或free,用e_j=alloc表示第j个事件用于分配第m_j个请求,用e_j=free表示第j个事件用于释放第m_j个请求;该事件所对应的内存大小为其所属请求的内存大小,即z_{m_j}。
例如,如图4所示,在本公开实施例提供的内存分配方法的一个示例中,初始化当前已分配的内存块集合、当前空余内存块集合以及内存块相对关系链表(即图3中的步骤s120),包括如下步骤。
步骤s121:设置当前已分配的内存块集合为空集;
步骤s122:设置当前空余内存块集合为空集;以及
步骤s123:对于每个请求,设置内存块相对关系链表中内存块的起始地址比请求对应的内存块的起始地址低的第一个请求为空、内存块的起始地址比请求对应的内存块的起始地址高的第一个请求为空。
例如,首先可以设置计数器i=0;当前已分配的内存块集合
例如,如图5a和图5b所示,在本公开实施例提供的内存分配方法的一个示例中,处理每个分配事件和每个释放事件(即图3中的步骤s130),包括如下步骤。
如图5a所示,对于分配事件:
步骤s131:如果当前空余内存块集合为空集,则在当前空余内存块集合中加入分配事件对应的内存大小的内存块到当前空余内存块集合中;
步骤s132:如果当前空余内存块集合不为空集,在当前空余内存块集合中寻找不小于分配事件对应的内存大小的最小的一段连续内存块作为空闲内存块,如果不存在这样的内存块,将当前空余内存块集合中最大的内存块的大小修改为分配事件对应的内存大小并将其作为空闲内存块;
步骤s133:将空闲内存块从当前空余内存块集合中移除,如果空闲内存块的大小大于分配事件对应的内存大小,则将空闲内存块的大小与分配事件对应的内存大小的差对应的内存块插入到当前空余内存块集合中;
步骤s134:在当前已分配的内存块集合中查找起始地址小于空闲内存块的起始地址条件下具有最高起始地址的最高内存块,设置内存块的起始地址比请求对应的内存块的起始地址低的第一个请求对应于最高内存块,如果查找不到最高内存块,则设置内存块的起始地址比请求对应的内存块的起始地址低的第一个请求为空;
步骤s135:在当前已分配的内存块集合中查找起始地址大于空闲内存块的起始地址条件下具有最低起始地址的最低内存块,设置内存块的起始地址比请求对应的内存块的起始地址高的第一个请求对应于最低内存块,如果查找不到最低内存块,则设置内存块的起始地址比请求对应的内存块的起始地址高的第一个请求为空。
如图5b所示,对于释放事件:
步骤s136:将释放事件对应的内存块从当前已分配的内存集合中移除,并将释放事件对应的内存块加入当前空余内存块集合;
步骤s137:如果当前空余内存块集合中存在与释放事件对应的内存块地址连续的内存块,则将其与释放事件对应的内存块合并。
例如,对于分配事件,如果当前空余内存块集合v为空,则新加入该分配事件对应的内存大小为z_{m_i}的一段内存块到当前空余内存块集合v中。在当前空余内存块集合v中寻找不小于z_{m_i}的最小的连续一段内存块作为空闲内存块;如果不存在这样的内存块,则取当前空余内存块集合v中最大的内存块,并将其大小修改为z_{m_i}。用c表示上一步中找到的空闲内存块,将c从当前空余内存块集合v中移除。如果c>z_{m_i},则将c-z_{m_i}插入到当前空余内存块集合v中。在当前已分配的内存块集合u中查询起始地址比c小的起始地址最高块a,以及起始地址比c大的起始地址最低块b,如果不存在则相应记作null,令prev_{m_i}=a,next_{m_i}=b,即设置内存块的起始地址比请求对应的内存块的起始地址低的第一个请求对应于最高内存块,如果查找不到最高内存块,则设置内存块的起始地址比请求对应的内存块的起始地址低的第一个请求为空,设置内存块的起始地址比请求对应的内存块的起始地址高的第一个请求对应于最低内存块,如果查找不到最低内存块,则设置内存块的起始地址比请求对应的内存块的起始地址高的第一个请求为空。
例如,对于释放事件,将释放事件m_i对应的内存块从当前已分配的内存块集合u中移除,并加入当前空余内存块集合v;如果当前空余内存块集合v中有与其地址连续的内存块,则将其与释放事件对应的内存块合并。
例如,对于一个分配或释放事件处理完毕后,设置计数器i=i+1,直到i=2n。也就是说,可以通过计数器累进的方式,处理每个分配事件和每个释放事件(例如n个分配事件和n个释放事件)。
例如,如图6所示,在本公开实施例提供的内存分配方法的一个示例中,根据分配事件和释放事件的处理结果获取相对内存位置关系(即图3中的步骤s140),包括如下步骤。
步骤s141:对于每个请求,初始化请求的对应的内存块的起始地址大于等于第一请求集合中每个请求对应的内存块的结束地址;
步骤s142:将第一请求集合与内存块的起始地址比请求对应的内存块的起始地址低的第一个请求的集合的并集作为更新后的第一请求集合;以及
步骤s143:将请求对应的内存块的最大结束地址小于等于内存块的起始地址比请求对应的内存块的起始地址高的第一个请求的集合与请求的集合的并集作为第二请求集合。
例如,在步骤s141中,对0≤i<n,初始化输出结果
例如,在步骤s142中,对0≤i<n,令below_i=below_i∪{prev_i},即将第一请求集合与内存块的起始地址比请求对应的内存块的起始地址低的第一个请求的集合的并集作为更新后的第一请求集合。
例如,在步骤s143中,对0≤i<n,令below_{next_i}=below_{next_i}∪{i},即将请求对应的内存块的最大结束地址小于等于内存块的起始地址比请求对应的内存块的起始地址高的第一个请求的集合与请求的集合的并集作为第二请求集合。
例如,如图7所示,在本公开实施例提供的内存分配方法的一个示例中,根据相对内存位置关系计算最优解(即图1中的步骤s200),包括如下步骤。
步骤s210:初始化每个请求对应的内存块的起始地址;
步骤s220:对于每个请求,如果请求的对应的内存块的起始地址大于等于第一请求集合中每个请求对应的内存块的结束地址,则设置请求对应的内存块的起始地址为零;以及
步骤s230:对于每个请求,如果存在请求的对应的内存块的起始地址小于第一请求集合中每个请求对应的内存块的结束地址,则对于所有的第一请求集合中的每个请求计算其对应的内存块的起始地址。
例如,在本公开实施例提供的内存分配方法的一个示例中,对于所有的第一请求集合中的每个请求计算其对应的内存块的起始地址,包括:计算所有的第一请求集合中的每个请求对应的内存块的起始地址和长度之和作为请求的起始内存地址。
例如,在步骤s100中已经计算出了below_i,即冲突请求间的相对内存位置关系。为了求解相对内存位置关系计算最优解,对于0≤i<n,初始化a_i=null;如果a_i不是null,则无需计算;如果
例如,计算当前已分配的内存块集合u、当前空余内存块集合v的操作可以用平衡二叉搜索树和线性链表来实现。例如,步骤s200中计算的复杂度级别是o(n)的,因此总的复杂度级别是o(nlogn)。因此,本公开实施例提供的内存分配方法能够高效处理大规模的数据流图。
示例性地,本公开实施例的内存分配方法为用于深度模型(指深度神经网络模型)训练的内存分配方法。通过该方法,可以有效地提高深度模型的训练速度。
本公开的实施例还提供一种用于内存分配的设备,如图8所示,内存分配设备800包括:一个或多个处理器801;一个或多个存储器802;以及存储在存储器802中的计算机程序指令,在计算机程序指令被处理器801运行时执行以下步骤:计算冲突请求间的相对内存位置关系;以及根据相对内存位置关系计算内存分配的最优解。
例如,处理器801可以是中央处理单元(cpu)或者具有数据处理能力和/或指令执行能力的其它形式的处理单元,该cpu例如可以是单核或多核cpu等,例如可以是基于x86架构或arm架构等,例如可以是并行计算方式或串行计算方式等,本公开的实施例不限于此。
例如,存储器802可以包括一个或多个计算机程序产品,计算机程序产品可以包括各种形式的计算机可读存储介质,例如易失性存储器和/或非易失性存储器。易失性存储器例如可以包括随机存取存储器(ram)和/或高速缓冲存储器(cache)等。非易失性存储器例如可以包括只读存储器(rom)、硬盘、闪存等。在计算机可读存储介质上可以存储一个或多个计算机程序指令并且还可以存储该程序指令运行时所需要的数据或者该程序指令运行时产生的数据,处理器801可以运行程序指令,以实现本公开实施例中(由处理器实现)的功能以及/或者其它期望的功能。
例如,在本公开实施例提供的用于内存分配的设备中,冲突请求是在同一时间要求占用的内存地址有重叠的请求。
例如,在本公开实施例提供的用于内存分配的设备中,计算冲突请求间的相对内存位置关系,包括:将每个请求转换为一个分配事件和一个释放事件,并按时间对每个分配事件和每个释放事件排序,并获取每个事件对应的内存大小;初始化当前已分配的内存块集合、当前空余内存块集合以及内存块相对关系链表;处理每个分配事件和每个释放事件;根据分配事件和释放事件的处理结果获取相对内存位置关系。
例如,在本公开实施例提供的用于内存分配的设备中,初始化当前已分配的内存块集合、当前空余内存块集合以及内存块相对关系链表,包括:设置当前已分配的内存块集合为空集;设置当前空余内存块集合为空集;对于每个请求,设置内存块相对关系链表中内存块的起始地址比请求对应的内存块的起始地址低的第一个请求为空、内存块的起始地址比请求对应的内存块的起始地址高的第一个请求为空。
例如,在本公开实施例提供的用于内存分配的设备中,处理每个分配事件和每个释放事件,包括:对于分配事件,如果当前空余内存块集合为空集,则在当前空余内存块集合中加入分配事件对应的内存大小的内存块到当前空余内存块集合中;如果当前空余内存块集合不为空集,在当前空余内存块集合中寻找不小于分配事件对应的内存大小的最小的一段连续内存块作为空闲内存块,如果不存在这样的内存块,将当前空余内存块集合中最大的内存块的大小修改为分配事件对应的内存大小并将其作为空闲内存块;将空闲内存块从当前空余内存块集合中移除,如果空闲内存块的大小大于分配事件对应的内存大小,则将空闲内存块的大小与分配事件对应的内存大小的差对应的内存块插入到当前空余内存块集合中;在当前已分配的内存块集合中查找起始地址小于空闲内存块的起始地址条件下具有最高起始地址的最高内存块,设置内存块的起始地址比请求对应的内存块的起始地址低的第一个请求对应于最高内存块,如果查找不到最高内存块,则设置内存块的起始地址比请求对应的内存块的起始地址低的第一个请求为空;在当前已分配的内存块集合中查找起始地址大于空闲内存块的起始地址条件下具有最低起始地址的最低内存块,设置内存块的起始地址比请求对应的内存块的起始地址高的第一个请求对应于最低内存块,如果查找不到最低内存块,则设置内存块的起始地址比请求对应的内存块的起始地址高的第一个请求为空;对于释放事件,将释放事件对应的内存块从当前已分配的内存集合中移除,并将释放事件对应的内存块加入当前空余内存块集合;如果当前空余内存块集合中存在与释放事件对应的内存块地址连续的内存块,则将其与释放事件对应的内存块合并。
例如,在本公开实施例提供的用于内存分配的设备中,根据分配事件和释放事件的处理结果获取相对内存位置关系,包括:对于每个请求,初始化请求的对应的内存块的起始地址大于等于第一请求集合中每个请求对应的内存块的结束地址;将第一请求集合与内存块的起始地址比请求对应的内存块的起始地址低的第一个请求的集合的并集作为更新后的第一请求集合;将请求对应的内存块的最大结束地址小于等于内存块的起始地址比请求对应的内存块的起始地址高的第一个请求的集合与请求的集合的并集作为第二请求集合。
例如,在本公开实施例提供的用于内存分配的设备中,根据相对内存位置关系计算最优解,包括:初始化每个请求对应的内存块的起始地址;对于每个请求,如果请求的对应的内存块的起始地址大于等于第一请求集合中每个请求对应的内存块的结束地址,则设置请求对应的内存块的起始地址为零;对于每个请求,如果存在请求的对应的内存块的起始地址小于第一请求集合中每个请求对应的内存块的结束地址,则对于所有的第一请求集合中的每个请求计算其对应的内存块的起始地址。
例如,在本公开实施例提供的用于内存分配的设备中,对于所有的第一请求集合中的每个请求计算其对应的内存块的起始地址,包括:计算所有的第一请求集合中的每个请求对应的内存块的起始地址和长度之和作为请求的起始内存地址。
本公开的实施例还提供一种用于内存分配的设备,如图9所示,内存分配的设备900包括:相对内存位置计算装置910和内存分配最优解计算装置920。相对内存位置计算装置910被配置为计算冲突请求间的相对内存位置关系;内存分配最优解计算装置920被配置为根据相对内存位置关系计算内存分配的最优解。
例如,在本公开实施例提供的用于内存分配的设备900中,相对内存位置计算装置910包括:排序模块911、第一初始化模块912、处理模块913和相对内存位置关系获取模块914。排序模块911被配置为将每个请求转换为一个分配事件和一个释放事件,并按时间对每个分配事件和每个释放事件排序,并获取每个事件对应的内存大小;第一初始化模块912被配置为初始化当前已分配的内存块集合、当前空余内存块集合以及内存块相对关系链表;处理模块913被配置为处理每个分配事件和每个释放事件;相对内存位置关系获取模块914被配置为根据分配事件和释放事件的处理结果获取相对内存位置关系。
例如,相对内存位置计算装置910中的排序模块911、第一初始化模块912、处理模块913和相对内存位置关系获取模块914可以由图8中所示的处理器801和存储器802实现。
例如,在本公开实施例提供的用于内存分配的设备中,内存分配最优解计算装置920包括:第二初始化模块921和内存块起始地址计算模块922。第二初始化模块921被配置为初始化每个请求对应的内存块的起始地址;内存块起始地址计算模块922被配置为对于每个请求,如果请求的对应的内存块的起始地址大于等于第一请求集合中每个请求对应的内存块的结束地址,则设置请求对应的内存块的起始地址为零;对于每个请求,如果存在请求的对应的内存块的起始地址小于第一请求集合中每个请求对应的内存块的结束地址,则对于所有的第一请求集合中的每个请求计算其对应的内存块的起始地址。
例如,内存分配最优解计算装置920中的第二初始化模块921和内存块起始地址计算模块922也可以由图8中所示的处理器801和存储器802实现。
例如,本公开实施例提供的内存分配方法和设备可以得到一个较优的内存分配方案,且分配方案的代价小、运行速度快。
示例性地,本公开实施例的内存分配设备为用于深度模型训练的内存分配设备。
虽然上文中已经用一般性说明及具体实施方式,对本公开作了详尽的描述,但在本公开实施例基础上,可以对之作一些修改或改进,这对本领域技术人员而言是显而易见的。因此,在不偏离本公开精神的基础上所做的这些修改或改进,均属于本公开要求保护的范围。