好的,这个文件是410k行代码。现在我只需1.4秒就能解析它,但我需要它更快。但是这个文件有一些奇怪的地方。。。在
文件的结构如下(感谢ARM):ARM fromelf
基本上,我将所有这些解析到一个映射中,其中的键是结构的名称,在这种情况下,由于ARM生成警告,可以复制这些映射。本例中的值是后面的字段。在
有没有一种方法可以使用线程将任务分成多个线程,将数据添加到同一个映射中?在
注:不是找人帮我做这件事,我只是提供了一个文件结构的例子,这样你就会明白我不能只处理每一行,而是要处理[开始:结束]以结构为基础。在
根据请求,我正在分析的示例:
; Structure, Table , Size 0x104 bytes, from inputfile.cpp
|Table.TableSize| EQU 0 ; int
|Table.Data| EQU 0x4 ; array[64] of MyClassHandle
; End of Structure Table
; Structure, Box2 , Size 0x8 bytes, from inputfile.cpp
|Box2.| EQU 0 ; anonymous
|Box2..| EQU 0 ; anonymous
|Box2...Min| EQU 0 ; Point2
|Box2...Min.x| EQU 0 ; short
|Box2...Min.y| EQU 0x2 ; short
|Box2...Max| EQU 0x4 ; Point2
|Box2...Max.x| EQU 0x4 ; short
|Box2...Max.y| EQU 0x6 ; short
; Warning: duplicate name (Box2..) present in (inputfile.cpp) and in (inputfile.cpp)
; please use the --qualify option
|Box2..| EQU 0 ; anonymous
|Box2...Left| EQU 0 ; unsigned short
|Box2...Top| EQU 0x2 ; unsigned short
|Box2...Right| EQU 0x4 ; unsigned short
|Box2...Bottom| EQU 0x6 ; unsigned short
; End of Structure Box2
; Structure, MyClassHandle , Size 0x4 bytes, from inputfile.cpp
|MyClassHandle.Handle| EQU 0 ; pointer to MyClass
; End of Structure MyClassHandle
; Structure, Point2 , Size 0x4 bytes, from defects.cpp
|Point2.x| EQU 0 ; short
|Point2.y| EQU 0x2 ; short
; End of Structure Point2
; Structure, __fpos_t_struct , Size 0x10 bytes, from C:\Program Files\DS-5\bin\..\include\stdio.h
|__fpos_t_struct.__pos| EQU 0 ; unsigned long long
|__fpos_t_struct.__mbstate| EQU 0x8 ; anonymous
|__fpos_t_struct.__mbstate.__state1| EQU 0x8 ; unsigned int
|__fpos_t_struct.__mbstate.__state2| EQU 0xc ; unsigned int
; End of Structure __fpos_t_struct
END
优化解析器代码或者用其他语言编写可能会更好。在
在标准的Python实现(“CPython”)中,有效地进行多进程的唯一方法是使用multiprocessing模块,它依赖于使用多个unix进程而不是线程(由于全局解释器锁,线程对于计算绑定的任务来说实际上是不可能的)。您可以使用共享内存对象甚至共享字典(请参见Managers),但基本上进程间通信非常昂贵,并且很快就会消耗多任务处理的优势。在
如果您的各个线程在解析期间不需要关于结构的全局信息,那么它们可以各自创建自己的字典,然后您可以在最后合并所有的字典。将一个(可选择的)Python对象从一个进程发送到另一个进程是很容易的,但是请考虑以下问题:您的任务是解析文本表示并创建内部表示。pickle和unpickle对象包括获取一个内部表示,从中生成一个字符串,然后在通信通道的另一端解析该字符串。换句话说,您的解析任务只会生成另一个解析任务,并为序列化带来一些额外的开销。除了unpickler可能是比您编写的更快的解析器之外,这不太可能是一个很大的胜利。这让我们回到优化解析器的问题上来。在
并行化问题的一部分通常是直截了当的,那就是在进程之间划分任务。假设要解析的块(
start:finish
)不是太大,也就是说,410k行由几千个这样的子任务组成,那么有一个简单的策略:[task_number * task_size, task_number * task_size)
。在这个简单算法的问题在于,它假定解析的开销与解析的字符数严格成正比,并且所有线程都将以相同的速度执行。因为这两种假设都不太可能,所以很有可能有些线程会比其他线程完成得更快,然后只会旋转轮子等待更多的工作。在
这可以通过将文件拆分成更小的部分来避免,并在每个线程完成正在处理的线程时获得下一个可用的部分。(当然,您必须协调工作队列,但这只是每个工作块的一个同步,这不是太多的开销。)但是,我不建议上面这样做,因为输入文件不是太大,可以分成非常小的部分。由于实际工作的开始和结束都需要通过实际扫描来找到,因此每个工作块都有一些相关的开销并且块越多,开销就越大。如果块足够小,就会有一些根本没有实际工作。正确地调整参数需要更多关于工作单元大小的知识,而不是问题所揭示的。在
相关问题 更多 >
编程相关推荐