发明内容
根据本发明的实施例,提供了一种快速将fastq文件均匀分片的方法,包括:
通过两个线程并发加载fastq文件,构造read数据并输出;
设置若干个分片,根据均匀分片算法将所述read数据分配到对应分片的分片缓存;
通过异步分片线程池中的异步分片线程,将所述分片缓存中的read数据写入对应分片的输出fastq文件中。
进一步地,所述通过两个线程并发加载fastq文件,构造read数据并输出,包括:
分配第一线程、第二线程和一个数据块队列,设置该数据块队列的最大数据项个数限制以及数据块的大小;
在所述第一线程中,向对象内存复用池发出分配内存请求,等待分配一个所述数据块大小的数据块;
在所述第一线程中,按照所述数据块的大小读取所述fastq文件,将读取到的数据放到所述分配的数据块中,判断所述数据块队列是否达到所述最大数据项个数限制,如果是,则进入等待状态,直至所述数据块队列的数据项个数小于所述最大数据项个数限制,将所述数据块插入所述数据块队列的队尾;否则,将所述数据块插入所述数据块队列的队尾;
继续判断所述fastq文件是否读取完毕,如果已读取完毕,则设置数据块队列结束标记,并结束第一线程;如果未读取完毕,则返回等待分配数据块,继续加载fastq文件;
在所述第二线程中,判断所述数据块队列是否为空且设置结束标记,如果所述数据块队列为空且设置结束标记,则结束第二线程;如果所述数据块队列为空且没有设置结束标记,则进入等待状态,直到所述数据块队列不为空或者被设置结束标记为止;如果所述数据块队列不为空,则从所述数据块队列的头部取出数据块,得到fastq块数据;
顺序地将所述fastq块数据进行换行解析,得到若干个read数据,并按次序逐个输出;
在所述数据块被消费后,向对象内存复用池发出释放内存请求。
进一步地,所述read数据存储于一块连续内存内,包括一个起始位置、一个结束位置和三个索引值,三个索引值设置于所述起始位置与所述结束位置之间,用于分别指向三个换行符的位置;所述三个换行符将所述起始位置与所述结束位置之间的数据分割成四行数据,其中第一行数据为信息行、第二行数据为序列行、第三行数据为注释行、第四行数据为质量行;所述换行符用于触发数据换行操作。
进一步地,所述根据均匀分片算法将所述read数据分配到对应分片的分片缓存,包括:
为每个分片分配一个分片缓存,定义计数索引;所述计数索引用于在分片缓存获取到read数据时,为该read数据分配索引值,且每获取到一个read数据,其对应的索引值加1;
获取所述read数据,计算所述获取到的read数据对应的分片序号,将所述read数据分配到所述分片序号对应分片,将所述对应分片的read数据插入对应的分片缓存中。
进一步地,所述计算所述获取到的read数据对应的分片序号,包括:
Qn=Pn%N
其中,Qn为第n个read数据对应的分片序号;Pn为第n个read数据的索引值;N为分片个数。
进一步地,所述将所述对应分片的read数据插入对应的分片缓存中,包括:
所述分片缓存包括一个缓存块和一个分片数据队列;设置所述缓存块的最大存储容量;所述分片数据队列用于按顺序存储相同分片的read数据;
通过对象内存复用池为所述分片缓存中的第一缓存块分配内存;
所述第一缓存块接收read数据,并判断所述read数据是否接收完毕,如果是,则将所述分片缓存设置结束标记,并结束缓存;否则,将所述read数据放入第一缓存块中,并判断所述第一缓存块是否达到预设的缓存块最大存储容量,如果所述第一缓存块达到预设的缓存块最大存储容量,则将所述第一缓存块插入分片数据队列的队尾,向对象内存复用池发送分配内存请求,通过对象内存复用池分配第二缓存块;如果所述第一缓存块未达到预设的缓存块最大存储容量,则继续接收read数据;
当所述第二缓存块被分配至所述分片缓存中时,判断当前read数据是否存在未被放入缓存块的数据,如果存在,则将当前read数据中未放入缓存块的数据放入第二缓存块中,然后返回所述第一缓存块接收read数据步骤;如果不存在,则直接返回所述第一缓存块接收read数据步骤。
进一步地,还包括:
在双端测序情况下,所述read数据为两个,分别为read1数据和read2数据;所述缓存块为两个,用于分别存放对应的read1数据和read2数据;将所述两个缓存块进行关联;
当存放有read1数据的缓存块达到预设的缓存块最大存储容量时,将该缓存块插入分片数据队列的队尾。
进一步地,还包括:
设置所述分片数据队列的最大缓存块数量;
在将所述第一缓存块或所述存放有read1数据的缓存块插入分片数据队列的队尾时,判断所述分片数据队列中的缓存块个数是否达到预设的最大缓存块数量,如果是,则进入等待状态,直至所述分片数据队列中的缓存块个数小于预设的最大缓存块数量为止;否则,将所述第一缓存块或所述存放有read1数据的缓存块插入分片数据队列的队尾。
进一步地,所述通过异步分片线程池中的异步分片线程,将所述分片缓存中的read数据写入对应分片的输出fastq文件中,包括:
在所述异步分片线程中,判断所述分片缓存的分片数据队列是否为空且设置结束标记,如果所述分片数据队列为空且设置结束标记,则结束该异步分片线程操作;如果所述分片数据队列为空且没有设置结束标记,则进入等待状态,直到所述分片数据队列不为空或者被设置结束标记为止;如果所述分片数据队列不为空,则从所述分片数据队列头部取出一个缓存块;所述异步分片线程池包括若干个异步分片线程,且每个异步分片线程唯一对应一个分片缓存,且不同异步分片线程之间相互独立;
从所述获取到的缓存块中进行反关联操作,如果得到反关联结果,则将所述获取到的缓存块与所述反关联结果分别写入对应分片的输出fastq文件中;如果未得到反关联结果,则将所述获取到的缓存块写入对应分片的输出fastq文件中;
在所述缓存块被消费后,向对象内存复用池发出释放内存请求。
进一步地,还包括:
定义对象内存复用池,为所述对象内存复用池配置分配接口和释放接口,并预设对象内存复用池的最大存储容量;所述对象内存复用池用于回收被释放的对象内存,并当待分配对象内存时,复用回收的对象内存进行分配;
当所述对象内存复用池接收到分配内存请求时,通过所述对象内存复用池的分配接口判断所述对象内存复用池是否为空,如果是,则从操作系统内存分配接口分配所述分配内存请求对应的对象内存;否则从所述对象内存复用池中移出一个与所述分配内存请求对应的对象内存,根据所述分配内存请求进行分配;
当所述对象内存复用池接收到释放内存请求时,通过所述对象内存复用池的释放接口判断所述对象内存复用池是否达到所述对象内存复用池的最大存储容量,如果是,则从操作系统内存释放接口释放所述释放内存请求对应的对象内存;否则将所述释放内存请求对应的对象内存放入所述对象内存复用池。
应当理解,发明内容部分中所描述的内容并非旨在限定本发明的实施例的关键或重要特征,亦非用于限制本发明的范围。本发明的其它特征将通过以下的描述变得容易理解。
本发明采用均匀分片的方法避免传统方法中需要完整遍历fastq文件来统计read总个数的过程,大大节省程序的耗时,同时利用并行的工作方式,多个线程同时协同作用,提升了作业效率,并通过使用分片缓存,极大减少了系统锁的调用次数,以及对线程安全队列和文件系统写数据接口的操作次数,降低操作系统负载;通过异步线程池并发多分片fastq输出,充分利用了CPU多核能力和存储的高吞吐能力,从而保证了最终分片fastq文件的高效输出,实现快速将fastq文件均匀分片的目的。
具体实施方式
为使本发明实施例的目的、技术方案和优点更加清楚,下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的全部其他实施例,都属于本发明保护的范围。
另外,本文中术语“和/或”,仅仅是一种描述关联对象的关联关系,表示可以存在三种关系,例如,A和/或B,可以表示:单独存在A,同时存在A和B,单独存在B这三种情况。另外,本文中字符“/”,一般表示前后关联对象是一种“或”的关系。
本发明中,采用均匀分片的方法避免传统方法中需要完整遍历fastq文件来统计read总个数的过程,大大节省程序的耗时,同时利用并行的工作方式,多个线程同时协同作用,提升了作业效率,同时采用优化定义的read存储结构,减少了每条read数据在其生命期内的字符串拷贝和重串联的次数,并通过使用分片缓存,极大减少了系统锁的调用次数,以及对线程安全队列和文件系统写数据接口的操作次数,降低操作系统负载;通过异步线程池并发多分片fastq输出,充分利用了CPU多核能力和存储的高吞吐能力,从而保证了最终分片fastq文件的高效输出。应用对象内存复用池,降低了整个分离过程中向操作系统申请和释放内存的请求次数,从而降低操作系统负载,释放出更多的CPU资源给其他运算逻辑,达到快速将fastq文件均匀分片的目的。
图1示出了根据本发明的实施例的快速将fastq文件均匀分片方法的流程图。
该方法S100包括:
S110、通过两个线程并发加载fastq文件,构造read数据并输出。
所述fastq文件一般都非常大,小到几个GB,大到数十上百GB大小的都有。为了进行下一步的基因序列分析,需要先将这种原始fastq文件拆分为大小均匀的更小的fastq文件分片。此过程首先需要快速进行分片,也需要保证每个分片之间大小基本上均匀。
作为本发明的一种实施例,本方法设计了两个线程,即第一线程和第二线程;所述第一线程用于分块读取fastq文件数据,并将读取到的数据块插入数据块队列;所述第二线程用于从数据块队列中取出数据块,并对数据块中数据进行解析,得到read数据进行输出。
本发明采用并发加载fastq文件和解析read数据的方式,相比传统的逐行串行加载fastq文件,再解析read数据的方式,由于有效利用了CPU的多核能力,并且增加了加载fastq文件的IO大小,从而使性能大幅提升。
进一步地,作为本发明的一种实施例,通过所述两个线程并发加载fastq文件,构造read数据并输出的过程,如图2所示,包括:
S111、分配第一线程、第二线程和一个数据块队列,设置该数据块队列的最大数据项个数限制以及数据块的大小;所述数据块队列包括若干个数据块,且按序排列;其不为空的时候,至少有一头部数据块和尾部数据块。定义所述数据块队列的存取逻辑是通过尾部存入、通过头部取出。为所述数据块设置一固定大小,例如1MB;用于作为数据存取大小标准,使每次加载的fastq块数据大小相等。
S112、在所述第一线程中,向对象内存复用池发出分配内存请求,等待分配一个所述数据块大小的数据块;所述对象内存复用池用于回收被释放的对象内存,并当待分配对象内存时,对象内存复用池复用回收的对象内存进行分配。当所述对象内存复用池接收到分配内存请求时,如果当前对象内存复用池中有可分配的内存,则根据分配内存请求对应的待分配内存大小分配内存,并返回所述分配内存请求。如果当前对象内存复用池中没有可分配的内存,则从操作系统内存分配接口分配所述分配内存请求对应的对象内存。
S113、在所述第一线程中,按照所述数据块的大小读取所述fastq文件,判断所述数据块队列是否达到所述最大数据项个数限制,如果是,则进入等待状态,直至所述数据块队列的数据项个数小于所述最大数据项个数限制,将所述数据块插入所述数据块队列的队尾,此时被插入的数据块即为所述数据块队列的尾部;否则,将所述数据块插入所述数据块队列的队尾;继续判断所述fastq文件是否读取完毕,如果已读取完毕,则设置数据块队列结束标记,并结束第一线程;如果未读取完毕,则返回等待分配数据块,继续加载fastq文件。
S114、在所述第二线程中,判断所述数据块队列是否为空且设置结束标记,如果所述数据块队列为空且设置结束标记,则结束第二线程;如果所述数据块队列为空且没有设置结束标记,则进入等待状态,直到所述数据块队列不为空或者被设置结束标记为止;如果所述数据块队列不为空,则从所述数据块队列的头部取出数据块,得到fastq块数据。
S115、顺序地将所述fastq块数据进行换行解析,得到若干个read数据,并按次序逐个输出,在所述数据块被消费后,向对象内存复用池发出释放该数据块内存的请求。
所述第一线程与第二线程同时并行处理,即所述第一线程陆续加载所述fastq文件中的数据块到所述数据块队列中,同时所述第二线程逐个从所述数据块队列的头部依次提取数据块,并在内存中进行解析,通过解析过程,从一个个数据块中解析出read数据。利用并行的工作方式,使多线程同时协同作业,提升了作业效率,极大地减少了作业时间。
进一步地,所述read数据存储于一块连续内存内,包括一个起始位置、一个结束位置和三个索引值,三个索引值设置于所述起始位置与所述结束位置之间,用于分别指向三个换行符的位置;所述三个换行符将所述起始位置与所述结束位置之间的数据分割成四行数据,其中第一行数据为信息行、第二行数据为序列行、第三行数据为注释行、第四行数据为质量行;所述换行符用于触发数据换行操作。
在本发明的一种实施例中,如图3(a)所示,为使用优化定义的read存储结构来存储一个read数据。即使用一整块连续内存来存储read的四行完整数据,给这样一块连续内存命名为READ,起始位置为0,结束位置为end。引入起始位置0和结束位置end为了方便描述read的存取划分,实际的操作中,连续存储read四行数据的READ是一个string类型,即字符串类型,其能够得到READ的起始位置和结束位置。使用三个索引值来分别指向read数据的第一行、第二行、第三行数据的换行符的位置,例如LF_pos1、LF_pos2和LF_pos3。三个换行符将一段数据分割成4行数据,其中第一行数据为信息行,表示为READ[0,LF_pos1),表示0到字符LF_pos1之间的左闭右开区间;第二行数据为序列行,表示为READ[LF_pos1+1,LF_pos2),表示字符LF_pos1+1到字符LF_pos2之间的左闭右开区间;第三行数据为注释行,表示为READ[LF_pos2+1,LF_pos3),表示字符LF_pos2+1到字符LF_pos3之间的左闭右开区间;第四行数据为质量行,表示为READ[LF_pos3+1,end),表示字符LF_pos3+1到READ结束位置end之间的左闭右开区间。使用一整块连续内存来完整存储read的四行read数据,并将得到的每个read数据按照顺序进行输出。
在本发明的一种实施例中,如图3(b)所示,为使用传统的read存储结构来存储一个read数据。即使用四段相互不连续的内存来分别存储一个read的四行数据,其中第一行为信息行数据、第二行为基因序列数据、第三行为注释数据、第四行为序列质量数据;以此read数据内存格式顺序地逐个输出read数据。
使用传统的read存储结构,在把read数据写入存储的过程中,如果省去在内存中将四行数据重新连接到一个连续内存的过程,而采用直接单独写每行数据,那么,对于read的每一行数据就会产生一个对存储的写IO,4行数据就会有4个写IO,即一个read数据就需要4个写IO才能把数据写到存储。而在内存中将四行数据重新连接到一个连续内存之后,只需要一个写IO就能完成相同的工作。前者比后者多出了3个写IO操作。而每个写IO操作会经由操作系统应用层到内核层,再到设备驱动,最后到存储硬件,这是一个很长的IO栈。相对于在内存中将四行数据重新连接到一个连续内存的操作来说,它是一个很漫长的过程。有10亿个read数据就会多出10亿*3=30亿个这样的写IO操作,这会相当慢。所以,在使用传统read存储结构时,必须要先重新连接4行数据到一个连续内存,再写到存储中。
下表为传统read存储结构与本发明优化后的read存储结构在read生命期各个阶段的操作对比:
由上表可知,在一个read的生命周期中,优化后的read存储结构比传统的存储结构少了7次数据拷贝操作,少了一次分配和释放内存的操作。将read数据放大到10亿条,就少了70亿次数据拷贝和10亿次内存分配、10亿次释放内存操作。从实际测试结果来看,模拟测试10亿条read数据逐个经历上表描述的生命周期所有阶段,传统read存储结构耗时11分钟,而优化后的read存储结构耗时4分钟。
综上,通过对read存储结构的优化,大大降低了对read数据的基本操作次数。例如,假设原始fastq文件中有10亿条read,采用优化后的read存储结构,在整个基因数据分离期间,减少了10亿*4=40亿次四行数据拆分拷贝操作,减少了10亿次四行数据重组拼接成连续内存的操作。从而释放了一大块额外的没必要的CPU和内存消耗。
S120、设置若干个分片,根据均匀分片算法将所述read数据分配到对应分片的分片缓存,包括:
S121、为每个分片分配一个分片缓存,那么假设设置N个分片,则有N个分片缓存与之一一对应。
S122、定义计数索引;所述计数索引用于在分片缓存获取到read数据时,为该read数据分配索引值,且每获取到一个read数据,其对应的索引值加1。
S123、获取所述read数据,计算所述获取到的read数据对应的分片序号,将所述read数据分配到所述分片序号对应分片,将所述对应分片的read数据插入对应的分片缓存中。
采用均匀分片算法,实现在运行时保证分片的均匀。从而避免程序一开始就需要完整遍历fastq文件来统计read总个数的过程。并且该算法的时间和空间复杂度都为O(1),大大节省程序耗时。
S1231、所述获取到的read数据对应的分片序号计算过程如下:
Qn=Pn%N
其中,Qn为第n个read数据对应的分片序号;Pn为第n个read数据的索引值;N为分片个数。%表示模运算,即求余数。
作为本发明的一种实施例,如果分片个数为10个,当前read数据的索引值为203,则当前read数据对应的分片序号为:
Qn=Pn%N=203%10=3
即,当前read数据需要分配到编号为3的分片中。
S1232、进一步地,将所述对应分片的read数据插入对应的分片缓存中,如图4所示,包括:
首先判断是单端测序还是双端测序情况,单端测序情况如下:
为每个分片分配一个分片缓存;所述分片缓存包括一个缓存块和一个分片数据队列;设置缓存块的最大存储容量;所述分片数据队列用于按顺序存储同一分片的read数据;
通过对象内存复用池为所述分片缓存中的第一缓存块分配内存;
所述第一缓存块接收read数据,并判断所述read数据是否接收完毕,如果是,则将所述分片缓存设置结束标记,并结束缓存;否则,将所述read数据放入第一缓存块中,并判断所述第一缓存块是否达到预设的缓存块最大存储容量,如果所述第一缓存块达到预设的缓存块最大存储容量,则将所述第一缓存块插入分片数据队列的队尾,然后向对象内存复用池发送分配内存请求,通过对象内存复用池分配第二缓存块。
当第二缓存块被分配至所述分片缓存中时,判断当前read数据是否存在未被放入缓存块的数据,如果存在,则将当前read数据中未放入缓存块的数据放入第二缓存块中,然后返回执行接收read数据步骤;如果不存在,则直接返回执行接收read数据步骤。
当存放有read1的缓存块达到预设的缓存块最大存储容量时,将该缓存块插入分片数据队列的队尾。
进一步地,在双端测序情况下,所述read数据为两个,分别为read1和read2数据;所述缓存块为两个,用于分别存放对应的read1和read2数据;将所述两个缓存块进行关联。
进一步地,预先设置所述分片数据队列的最大缓存块数量;如果将所述第一缓存块插入分片数据队列的队尾时,所述分片数据队列中的缓存块个数达到预设的最大缓存块数量,则进入等待状态,直至所述分片数据队列中的缓存块个数小于预设的最大缓存块数量为止。
作为本发明的一种实施例,如图5所示,所述read数据插入分片缓存过程包括以下步骤:
S1232-1:为fastq文件的每一个输出分片分配一个独立的分片缓存,所述分片缓存包括一个缓存块和一个分片数据队列;所述缓存块为一固定存储容量的内存块,例如将所述缓存块容量大小为2MB。所述分片数据队列用于存储缓存块,并设置分片数据队列的最大缓存块数量,例如设置MaxCacheBlockNum为128。
S1232-2:使用对象内存复用池为分片缓存分配缓存块内存。
S1232-3:分片缓存中接收到一条对应分片的read数据,判断所述read数据是否接收完毕,如果是,则进入S1232-8;否则将所述read数据追加放入缓存块,并执行步骤S1232-4;所述对read数据是否获取完毕的判断,是通过识别底层文件系统提供的文件结束标记来实现的,例如,当读取fastq文件结束的时候,会获取到文件系统返回的EOF标记,EOF是endof file的英文简写,表示文件已经读取完毕。
S1232-4:判断所述缓存块是否被填满,如果是,则执行步骤S1232-5;否则,返回步骤S123-3;
S1232-5:把所述缓存块插入分片数据队列的队尾,在插入时,判断分片数据队列已有的缓存块个数是否已达到预设的最大缓存块数量MaxCacheBlockNum,如果是,则进入“满等”状态,直至分片数据队列中有空间满足插入为止;如果不是,则进入S1232-6。所述“满等”状态为一种等待状态,等待原因是由于分片数据队列处于满载状态,导致待插入缓存块没有空间进行插入,故处于等待状态。所述分片数据队列中有空间满足插入,是通过分片数据队列中已有的缓存块被取出消费后,释放队列内存空间,使处于“满等”状态的缓存块能够插入到释放的内存空间。
S1232-6:通过对象内存复用池分配一个新的缓存块;
S1232-7:判断当前read数据是否存在未被放入缓存块的数据,如果存在,则将当前read数据中未放入缓存块的数据放入新分配的缓存块中,然后返回S1232-3;如果不存在,则直接返回S1232-3。
S1232-8:将所述分片缓存设置结束标记,并结束缓存。
如图6所示,所述从所述分片缓存中取出read数据,过程包括:
判断所述分片缓存的分片数据队列是否为空且设置结束标记,如果所述分片数据队列为空且设置结束标记,则结束该过程;如果所述分片数据队列为空且没有设置结束标记,则进入等待状态,直到所述分片数据队列不为空或者被设置结束标记为止;如果所述分片数据队列不为空,则从所述分片数据队列头部取出一个缓存块。所述“空等”状态是一种等待状态,等待原因是由于分片数据队列中是空队列,即无数据,导致无法从分片数据队列中取出数据,故处于等待状态。
在以具体实施例中,假设将10亿条read数据写入存储,没有使用分片缓存的时候,需要10亿个写IO把所有read数据写到存储。使用分片缓存后,假设一个缓存块2MB大小,可以放1.5万条read数据,那么10亿条read总共会用到大约6.6万个缓存块。写存储的时候,一个缓存块为一个写IO,即一次写2MB的数据。那么,在用了分片缓存以后,10亿条read数据只需要约6.6万个写IO就把数据写完。从10亿个IO降低到6.6万个IO,降低了5个数量级。
同样的道理,原本需要调用10亿次锁和解锁操作,而现在只需要6万多次。原本各需要10亿次的入队和出队操作,现在只需要6万多次。
综上,通过设计并应用的分片缓存技术,极大减少了线程安全队列的插入和移除操作,减少大量系统级接口的调用,大大降低了代码运行耗时,释放了大量CPU资源,极大地减轻了操作系统负载。
S130、通过异步分片线程池中的异步分片线程,将所述分片缓存中的read数据写入对应分片的输出fastq文件中,如图7所示,包括:
在所述异步分片线程中,判断所述分片缓存的缓存队列是否为空且设置结束标记,如果所述分片数据队列为空且设置结束标记,则结束该异步分片线程操作;如果所述分片数据队列为空且没有设置结束标记,则进入等待状态,直到所述分片数据队列不为空或者被设置结束标记为止;如果所述分片数据队列不为空,则从所述分片数据队列头部取出一个缓存块。
所述异步分片线程池包括若干个异步分片线程,且每个异步分片线程唯一对应一个分片缓存,且不同异步分片线程之间相互独立;即不同的异步分片线程之间可以并行处理。
进一步地,在所述获取到的缓存块中进行反关联,所述反关联即通过获取到的缓存块中的read数据尝试关联出与其关联的read数据,这种尝试会出现两种结果,一种是能够反关联出结果,另一种是无法反关联出结果,其中反关联的结果是存有与所述获取到的read数据相关联的read数据的缓存块。如果能够反关联出结果,说明是双端测序,此时需要将所述获取到的缓存块与其反关联结果分别写入对应分片的输出fastq文件中;如果未得到反关联结果,说明是单端测序,则将所述获取到的缓存块写入对应分片的输出fastq文件中。
在将所述获取到的read数据写入对应分片的输出fastq文件中之后,还需要判断当前分片缓存的分片数据队列是否为空,且存在结束标记,如果是,则结束当前异步分片线程操作,说明已经把fastq文件中的所有read数据都取出;当然,如果当前分片缓存的分片数据队列为空,但不存在结束标记,则表示仅当前分片数据队列中无数据,fastq文件还有未写入的未被消费的read数据,或者当前分片数据队列不为空,则返回重新执行S130,将所述分片缓存中的read数据写入对应分片的输出fastq文件中。
进一步地,如图8所示,本发明还对所有的分配和释放对象内存的地方进行了优化,具体定义了对象内存复用池。
为所述对象内存复用池配置分配接口和释放接口,并预设对象内存复用池的最大存储容量;所述对象内存复用池用于回收被释放的对象内存,并当待分配对象内存时,复用回收的对象内存进行分配。
当在分离read数据过程中会频繁用到的对象内存被释放时,对象内存复用池将这些内存回收到对象内存复用池中,而不是将这些对象内存还给操作系统;当处理逻辑下次需要这些内存时,对象内存复用池直接复用之前回收的内存,将其返回给处理逻辑,而不是向操作系统去申请所需内存。
所述对象内存复用池分配接口、对象内存复用池释放接口为调用函数,通过调用函数来分配和释放对象内存。
如图9所示,通过在分片缓存插入数据的逻辑中,复用对象内存复用池中的内存块。在分片缓存移出数据逻辑中,回收之前分配的内存块。程序很快就不会再向操作系统申请分配/释放缓存块的内存,完全是复用之前已经申请的固定量的内存块。
当接收到分配请求时,通过所述对象内存复用池分配接口判断所述对象内存复用池是否为空,如果是,则从操作系统内存分配接口分配所述分配请求对应的对象内存;否则从所述对象内存复用池中移出一个与所述分配请求对应的对象内存,根据所述分配请求进行分配。
当接收到释放请求时,通过所述对象内存复用池释放接口判断所述对象内存复用池是否达到对象内存复用池最大存储容量,如果是,则从操作系统内存释放接口释放所述释放请求对应的对象内存;否则将所述释放请求对应的对象内存放入所述对象内存复用池。
作为本发明的一种实施例,在对象内存复用池分配接口中,判断对象内存复用池是否为空,如果是,则直接从操作系统内存分配接口分配该对象内存;否则从对象内存复用池中移出一个对象,作为新分配的对象内存,返回对应的分配请求。
作为本发明的一种实施例,在对象内存复用池释放接口中,判断对象内存复用池是否被填满,如果是,则直接使用操作系统内存释放接口来释放该对象内存;否则将该对象内存直接放入对象内存复用池,并返回对应的释放请求。
作为本发明的一种实施例,如图10所示,在读取fastq和解析read逻辑中,即S110步骤中,在分块读取fastq线程中,复用对象内存复用池中回收的内存块。在解析read线程中,回收之前分配的内存块到对象内存复用池。以此达到良性循环,程序很快就不会再向操作系统申请分配或释放有关这里的内存。
本发明通过应用基于对象内存复用池的内存复用技术,极大减少了程序从操作系统分配和释放内存的次数,从而减少了大量系统开销,降低了操作系统负载,使程序内存使用量和CPU利用率趋于一个稳定、健康的状态。
通过将优化的read存储结构、分片缓存技术以及内存复用技术联合应用到将fastq文件均匀分片过程中,极大地缩短了将fastq文件进行分片的时间消耗。利用并行的工作方式,多个线程同时协同作用,提升了作业效率;同时采用优化定义的read存储结构,减少了每条read数据在其生命期内的字符串拷贝和重串联的次数;另外应用分片缓存技术,极大减少了系统锁的调用次数,以及对线程安全队列和文件系统写数据接口的操作次数;应用对象内存复用池,降低了整个分片过程中向操作系统申请和释放内存的请求次数,从而降低操作系统负载,释放出更多的CPU资源给其他运算逻辑;采用均匀分片算法,实现在运行时高效率地保证分片的均匀,从而达到快速将fastq文件均匀分片的目的。
通过使采用本发明的均匀分片方法,在分片时一直处于高效利用CPU、内存、存储吞吐的良性循环中,在保证输出结果正确性的同时,取得了非常好的性能结果。性能数据详细如下表:
如上表所示,是基于本发明的分片工具和传统的分片工具(这里用的是fastp)的性能比较。将同样的fastq文件均匀分片,基于本发明的分片工具将耗时减少了90%以上,很好地缩短了为后续基因数据分析准备数据的过程耗时。
本发明在每个环节都给出了单端测序和双端测序的不同处理方式,因此完美适配单端测序和双端测序,故无论是单端测序还是双端测序,本发明都能完美支持快速将fastq文件进行均匀分片的功能,并保证在两种模式下输出数据的正确性。
在本实施例的一些可选的实现方式中,在双端测序的情况下,fastq文件有两个,分别为r1和r2;输出两个read,分别为read1和read2。两个fastq文件的每一对read1和read2都具有相同的ID。
如图11所示为能够实施本发明的实施例的示例性电子设备。
设备1100包括中央处理单元(CPU)1101,其可以根据存储在只读存储器(ROM)1102中的计算机程序指令或者从存储单元1108加载到随机访问存储器(RAM)1103中的计算机程序指令,来执行各种适当的动作和处理。在RAM 1103中,还可以存储设备1100操作所需的各种程序和数据。CPU 1101、ROM 1102以及RAM 1103通过总线1104彼此相连。输入/输出(I/O)接口1105也连接至总线1104。
设备1100中的多个部件连接至I/O接口1105,包括:输入单元1106,例如键盘、鼠标等;输出单元1107,例如各种类型的显示器、扬声器等;存储单元1108,例如磁盘、光盘等;以及通信单元1109,例如网卡、调制解调器、无线通信收发机等。通信单元1109允许设备1100通过诸如因特网的计算机网络和/或各种电信网络与其他设备交换信息/数据。
处理单元1101执行上文所描述的各个方法和处理,例如方法S100。例如,在一些实施例中,方法S100可被实现为计算机软件程序,其被有形地包含于机器可读介质,例如存储单元1108。在一些实施例中,计算机程序的部分或者全部可以经由ROM 1102和/或通信单元1109而被载入和/或安装到设备1100上。当计算机程序加载到RAM 1103并由CPU 1101执行时,可以执行上文描述的方法S100的一个或多个步骤。备选地,在其他实施例中,CPU 1101可以通过其他任何适当的方式(例如,借助于固件)而被配置为执行方法S100。
本文中以上描述的功能可以至少部分地由一个或多个硬件逻辑部件来执行。例如,非限制性地,可以使用的示范类型的硬件逻辑部件包括:场可编程门阵列(FPGA)、专用集成电路(ASIC)、专用标准产品(ASSP)、芯片上系统的系统(SOC)、负载可编程逻辑设备(CPLD)等等。
用于实施本发明的方法的程序代码可以采用一个或多个编程语言的任何组合来编写。这些程序代码可以提供给通用计算机、专用计算机或其他可编程数据处理装置的处理器或控制器,使得程序代码当由处理器或控制器执行时使流程图和/或框图中所规定的功能/操作被实施。程序代码可以完全在机器上执行、部分地在机器上执行,作为独立软件包部分地在机器上执行且部分地在远程机器上执行或完全在远程机器或服务器上执行。
在本发明的上下文中,机器可读介质可以是有形的介质,其可以包含或存储以供指令执行系统、装置或设备使用或与指令执行系统、装置或设备结合地使用的程序。机器可读介质可以是机器可读信号介质或机器可读储存介质。机器可读介质可以包括但不限于电子的、磁性的、光学的、电磁的、红外的、或半导体系统、装置或设备,或者上述内容的任何合适组合。机器可读存储介质的更具体示例会包括基于一个或多个线的电气连接、便携式计算机盘、硬盘、随机存取存储器(RAM)、只读存储器(ROM)、可擦除可编程只读存储器(EPROM或快闪存储器)、光纤、便捷式紧凑盘只读存储器(CD-ROM)、光学储存设备、磁储存设备、或上述内容的任何合适组合。
此外,虽然采用特定次序描绘了各操作,但是这应当理解为要求这样操作以所示出的特定次序或以顺序次序执行,或者要求所有图示的操作应被执行以取得期望的结果。在一定环境下,多任务和并行处理可能是有利的。同样地,虽然在上面论述中包含了若干具体实现细节,但是这些不应当被解释为对本发明的范围的限制。在单独的实施例的上下文中描述的某些特征还可以组合地实现在单个实现中。相反地,在单个实现的上下文中描述的各种特征也可以单独地或以任何合适的子组合的方式实现在多个实现中。
尽管已经采用特定于结构特征和/或方法逻辑动作的语言描述了本主题,但是应当理解所附权利要求书中所限定的主题未必局限于上面描述的特定特征或动作。相反,上面所描述的特定特征和动作仅仅是实现权利要求书的示例形式。