Concurrency erlang进程和消息传递体系结构
我手头的任务是读取大文件的行,处理它们,并返回有序的结果 我的算法是:Concurrency erlang进程和消息传递体系结构,concurrency,process,erlang,messages,Concurrency,Process,Erlang,Messages,我手头的任务是读取大文件的行,处理它们,并返回有序的结果 我的算法是: 从评估工作负载的主流程开始(写在文件的第一行) 生成工作进程:每个工作进程将使用pread/3读取文件的一部分,处理该部分,并将结果发送给master master接收所有子结果、排序和返回 因此,工人之间基本上不需要沟通 我的问题: 如何在erlang进程数和内核数之间找到最佳平衡?所以,如果我为我拥有的每个处理器核心生成一个进程,会不会是我的cpu利用率不足 pread/3如何到达指定的行;它是否迭代文件中的所有行?pr
N
工作者,并在他们之间分配工作,等待回音。如果您不喜欢程序的运行方式,请在更改N
的同时重新运行程序
更棘手的方法是对大量时间进行基准测试,选择您认为有意义的最大值,将其放入池库中(如果您愿意;一些池用于预分配的资源,一些池用于可调整大小的资源),然后满足于一刀切的解决方案
但实际上,不存在简单的“最佳核数”。您可以在50个进程上运行它,如果需要,还可以在其中65000个进程上运行它;如果任务是令人尴尬的并行任务,虚拟机应该能够利用它们中的大部分,并使内核饱和pread/2-3
这样的函数需要一个字节偏移量。您的问题的措辞使您担心文件的行数。因此,您传递给工人的字节偏移量可能会跨越一行。如果块在这是我的行中的单词my
处结束\n当它开始时,一个工作人员将看到自己的行不完整,而另一个工作人员将只报告my行\n
,缺少前面的这是
一般来说,这类烦人的事情会导致你让第一个进程拥有文件并对其进行筛选,只会将一些文本交给工作人员处理;然后,该进程将充当某种协调人
此策略的优点在于,如果主进程知道作为消息发送的所有内容,它还知道何时收到所有响应,从而很容易知道何时返回结果。如果一切都是不相交的,那么你必须相信发起者和员工会告诉你“我们都失业了”,这是一组独特的独立信息
在实践中,您可能会发现,最有帮助的是了解与文件操作相关的有助于硬件使用寿命的do操作,而不是“有多少人可以一次读取文件”。只有一个硬盘(或SSD),所有数据都必须通过它;并行性最终可能会受到限制,以便于访问
- 确保你阅读的文本是二进制格式的;大型二进制文件(>64b)在全局二进制堆上分配,共享,并使用引用计数进行GC
- 交上需要做什么的信息,而不是做这件事的数据;这一个需要测量,但前置过程可以遍历文件,注意行的结束位置,只需将字节偏移量交给工作人员,以便他们自己去读取文件;请注意,您最终将读取文件两次,因此如果内存分配不是您的主要开销,那么这可能会更慢
- 确保以
或raw
模式读取文件;其他模式使用中间人进程来读取和转发数据(如果您通过集群Erlang节点中的网络读取文件,这非常有用)ram
和raw
模式将文件描述符直接提供给调用过程,速度更快ram
- 首先要担心编写一个清晰、可读且正确的程序。只有当它太慢时,你才应该尝试重构和优化它;第一次尝试,你可能会发现它已经足够好了
- 使用
和拆分行(使用{ok,Bin}=file:read_file(Path)
一次性读取整个文件binary:split(Bin,[global])
- 使用
然后在文件描述符上重复使用{ok,Io}=file:open(file[read,ram])
file:read\u line(Io)
- 使用
{ok,Io}=file:open(file,[read,raw,{read\u-ahead,BlockSiz