在Erlang w/o环境中执行计算密集型任务的最佳方法是什么?

在Erlang w/o环境中执行计算密集型任务的最佳方法是什么?,erlang,scalability,erlang-ports,erlang-driver,jinterface,Erlang,Scalability,Erlang Ports,Erlang Driver,Jinterface,指南讨论了不同的互操作性机制。以下是我的结论: 端口和Erl_接口程序:操作系统已调度,限制了可扩展性 端口驱动程序:危险,因为端口驱动程序中的碰撞会导致 我也很失望 C节点:节点服务器需要与Erlang应用程序一样扩展以避免 可伸缩性牺牲 NIFs:总和 他们很好地相处 一些人主张使用OpenCL,基本上是将需要大量资源的计算委托给GPU,同时让Erlang emulator拥有CPU。这听起来很不错,但是你需要在你的服务器上安装一个合适的GPU 使用JInterface并与为每个请求生成

指南讨论了不同的互操作性机制。以下是我的结论:

  • 端口和Erl_接口程序:操作系统已调度,限制了可扩展性

  • 端口驱动程序:危险,因为端口驱动程序中的碰撞会导致 我也很失望

  • C节点:节点服务器需要与Erlang应用程序一样扩展以避免 可伸缩性牺牲

  • NIFs:总和 他们很好地相处

一些人主张使用OpenCL,基本上是将需要大量资源的计算委托给GPU,同时让Erlang emulator拥有CPU。这听起来很不错,但是你需要在你的服务器上安装一个合适的GPU

使用JInterface并与为每个请求生成线程的Java进程通信可能是一种选择


那么,有没有人遇到过一个在实践中经过测试并证明效果良好的解决方案呢?

实际上,所有的解决方案都会出现。由于我一直与他们中的一些人密切合作,我可以说:

  • 端口是安全的,但端口通信速度较慢。如果端口崩溃,VM将继续工作。如果您不与端口广泛通信或不信任端口,这是您的选择

  • NIF速度非常快。如果你的数据流很好,你应该使用它们。当然,它们是不安全的,所以您必须仔细编写NIF库,并且最好学习一些C语言(大多数NIF创建者都会跳过这一点)。实际上,使用特定的模式很容易克服调度问题。您应该在从Erlang接收数据并从Erlang线程分离处理之后,启动执行实际作业的新C线程。所以您可以非常快地退出NIF函数,返回Erlang并等待来自C代码的消息

  • Java节点或C节点用于可以完全移动到节点的任务。那是一些漫长而繁重的工作


考虑到上述因素,您决定最适合您任务的方式

您链接到的NIF的描述看起来过时且不准确。例如,在调度程序上运行NIF“超过几微秒”不会导致问题;只有当NIF运行超过几毫秒时,才会发生这种情况。此外,提供了一种很好的方法来分解长NIF以避免调度程序问题,另外,实验NIF可以运行任意长时间,而不会导致调度程序打嗝。要使用脏调度程序功能,您需要在启用实验脏调度程序支持的情况下构建模拟器。我不认为使用实验性功能运行生产代码的想法会有很多爱好者。总的来说,NIF似乎有点危险。正如Loic所指出的,它们可能会使你的虚拟机崩溃。编译在Windows下使用它们的库是一场噩梦——我不喜欢在Windows上运行Erlang。实验性的脏调度程序功能有一天会成为常规功能,希望在Erlang 19中。我实现了Erlang/OTP的脏调度器功能,并在启用它的情况下运行了所有Erlang 17和18虚拟机,并且没有任何问题。另外,请看,这显示了将进程切换到脏调度器所涉及的少量开销。您是否同意没有银弹?端口是可伸缩性和可靠性之间的折衷,NIF对Erlang弹性是一个风险,除非写得很好。从集成的角度来看,一个可伸缩的C或Java节点可能非常适合。@coolfeature,与NIFs相比,独立节点的通信速度仍然较慢。Erlang只有有限的套接字池(如果我没有弄错的话),您必须序列化/反序列化数据。如果处理数据的时间明显大于序列化/传输/反序列化的时间,那么独立节点将适合您。