【问题标题】:Is it possible, in a conceptual level, to realize distribute computing in an assembly/compiled code level? [closed]在概念层面上,是否有可能在汇编/编译代码层面实现分布式计算? [关闭]
【发布时间】:2020-04-23 01:46:35
【问题描述】:

这个问题的目的是询问是否有可能有一些已编译的代码(从普通程序的角度考虑,不一定以任何特殊的方式[例如多线程]或任何特定的范例/语言编写)通过网络发送,以某种方式在另一台机器上的 cpu 中进行处理。

好的,所以这涉及到很多概念,我对分布式计算和内核/操作系统概念都不是特别熟悉,如果这个问题看起来太宽泛或太不集中,请原谅我;我会尽我所能保持在正轨上。

假设我们的代码中有一个函数的汇编代码(指令)。这是一个简单的函数,通过将 x 加 1 来获取 x 并输出 y。我知道在执行层面,CPU需要获取x的值,将其移入CPU寄存器,执行加法,最后执行RET指令。

从概念上讲,是否有可能通过网络传递指令以及执行所需的任何上下文信息?如果是这样,什么是必要的信息? CPU寄存器和指令的初始状态,甚至更多信息?

我猜内核将深入参与此类过程的协调,但我最难以意识到的是,我需要将信息的最小“包”组装成一条消息,以便计算机在网络的另一端将能够执行简单的计算,或者如果考虑到 PC 架构的限制,这根本没有意义。

那里有很多关于分布式计算的信息,但大多数人认为代码是以特定方式设计的。我对任何已经存在的代码的类似解决方案感兴趣。

【问题讨论】:

  • 甚至试图回答这个问题都非常复杂,因为它非常模糊......我们是在谈论将单个函数移动到其他地方运行吗?这是当前正在运行的功能吗?或者我们想要透明地编组一个函数调用,以便它在其他地方运行?函数调用之后,是控制流返回到原来的机器,还是流程应该在新机器上继续?那么应该如何处理多个线程呢?这个函数是否应该是纯函数? IO应该如何工作?我们在谈论什么架构? x86 上的普通 Linux?微型?
  • 如果您知道目标操作系统和架构,您可以在运行时编译一个动态库(Windows 为 dll,Linux 为 dylib,osx 为 dylib)导出具有特定导出名称和原型的函数,例如int __cdecl compute(int x)。将该 DLL 发送到服务器。在服务器上,加载 DLL 并调用该函数。
  • 这个问题太宽泛了,但是很有可能。最小是什么在很大程度上取决于代码,您需要知道目标,x86 不足通常需要更多细节,很可能是操作系统、版本、内核版本(如果适用)等库依赖项。几乎所有你需要在你的机器上运行的东西,你需要知道在远程机器上运行加上更多,因为理想情况下,你的机器上的二进制文件不会在没有安装程序或构建依赖项测试的情况下创建/安装。
  • 在 linux 上,您可以使用包管理系统根据应用程序的依赖项来发现其中的内容。
  • 或者使用与目标无关的语言,java,python等,那么你只需要知道解释器/虚拟机是否在那里。

标签: assembly distributed thread-synchronization message-passing compiled


【解决方案1】:

您给出的描述非常模糊,所以我在推测,但如果目标是“随机获取现有的本机代码并透明地在网络中移动它”,唯一的可能就是复制整个过程,这很类似于 Unix 衍生操作系统上的 fork - 除了新进程将在另一台机器上运行。

fork 实质上创建了当前运行进程的完整克隆,因此新进程拥有自己的所有内容的副本 - 私有内存、打开的文件描述符、内存映射文件等。这可以在本地提高效率(通过仅在实际更改时按需复制内存),但在远程情况下,您必须实际复制和发送所有内容;至于文件映射和合作,那将是一只坏猫,因为你必须在另一边拥有相同的文件系统(处于相同的状态),而对于管道之类的东西,操作系统必须透明地替换他们通过插座或其他东西。这些东西在本地已经很复杂了,远程这将是一场噩梦。

这是必要的,因为在这个级别您几乎丢失了所有高级信息 - 函数主要是一种约定,代码可以随意跳转并根据内存做任何事情。即使假设代码遵循一些调用约定,你也无法知道有多少参数,它们的类型,如果输入参数是指针,它指向的块的逻辑大小有多大(你会也必须编组)。


OTOH,如果您对“可远程处理”代码的功能设置一些限制,问题就会变得更容易处理。如果我们可以假设:

  • 代码是自包含的(没有随机跳转,可能全部打包在一个共享对象/dll 中)并且可重定位/与位置无关;
  • 没有使用全局状态(包括打开的文件/套接字)
  • 运行时知道这些可远程处理函数的参数,例如,它知道如何序列化/反序列化它们

然后可以轻松实施更外科手术的方法 - 并且过去已经以多种方式完成(想想 DCOM)。但这只是您在 OP 中似乎想到的“透明”方式。

【讨论】:

  • 有趣的事实:Mosix / OpenMosix(Linux 单系统映像集群)基本上是这样工作的。它不如主线 Linux 稳定。 (特别是在 SMP 系统上;开发人员没有任何 SMP 机器可供测试。)但它确实有效。当我在 2003 年到 2006 年担任系统发育研究小组的系统管理员时,我在我们的一个较旧的 10 节点集群上使用了它。
  • 啊哈,我一直很好奇它是如何工作的,但从未真正深入了解它。与我想象的方法(在主节点上远程处理系统调用)的主要区别很有意义 - 必须同步内核数据结构将是一团糟。
【解决方案2】:

这本质上就是https://en.wikipedia.org/wiki/OpenMosix 所做的:透明地将进程迁移到其他集群节点,使集群的行为类似于具有多个内核的单个系统。 (2008 年停止开发)。

它的工作原理是挂起一个进程并通过网络将其所有映射内存发送到另一个节点,然后它将在该节点运行。它具有系统调用在主节点上运行的机制,因此整个过程不必为此迁移回来,例如复制读取或写入系统调用所涉及的内存。

所有这些对程序都是完全透明的;它使您可以轻松地在集群上运行单线程程序,而无需像 Grid Engine 这样的集群作业调度程序。但这并不能帮助多线程程序同时利用多个节点中的 CPU。它太粗粒度了。 (这是 OpenMosix 被放弃的主要原因之一。)

【讨论】:

    猜你喜欢
    • 2011-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-14
    • 1970-01-01
    • 2015-02-25
    • 2012-12-27
    • 2012-07-14
    相关资源
    最近更新 更多