我最近碰到了一个bug,其中python库使用某个CPU指令,该指令存在于一个x86处理器上但不存在于另一个x86处理器上,导致程序意外崩溃(非法指令)系统但不是另一个。这让我想到了容器化的好处,为我的软件创建了一个明确定义的运行时环境。但是当我意识到这是多么低级别时,我的大脑停滞不前,而且我无法从推理中解读出来,也无法从互联网阅读中了解到像docker那样的软件隔离程度。
所以我的问题是:容器化软件(如Docker或LXC)是否能够模拟物理硬件上不存在的指令?并且完整的虚拟机是否能够处理它,如果一个容器不能?
以为我会填补空白,因为人们很好奇。
我遇到的具体情况是在尝试将Reed-Solomon擦除编码应用于数据对象时。我正在使用PyECLib库,它通过liberasurecode
库实现Vandermonde Reed-Solomon(我相信它会使用jerasure。)
这段代码在兼容处理器上运行时没有错误,但在某些旧处理器上产生Illegal instruction
异常:
from pyeclib.ec_iface import ECDriver
ec_driver = ECDriver(k=1, m=5, ec_type='liberasurecode_rs_vand')
ec_driver.encode(b'foo')
我在多个Linux平台上使用Python 3.6。事情肆虐的一个值得注意的案例是在下面指定的处理器上运行Fedora 25的LXC容器中,但我敢打赌LXC和Fedora几乎没有关系。
我已经尝试了pyeclib 1.4和1.1,并且发生了同样的事情。
这些处理器使我的程序崩溃:
以下是一些工作正常的处理器:
答案 0 :(得分:4)
容器不会翻译说明。在容器中运行的程序与在同一台机器上运行的任何其他程序完全相同,除了它具有某些事物的单独(“命名空间”)实例,例如文件系统,网络堆栈和系统主机名。 CPU不会被模拟或虚拟化(无论如何都要比平常更多。)
虚拟机可以支持主机上不支持的指令,但它们不一定 。如果他们这样做,通常会产生相当大的性能成本。
答案 1 :(得分:3)
实际的答案是,不,目前没有产品能够做到这一点。
怀疑并不奇怪。事实上,不久之前,即使没有VM,ARM处理器也可以支持这种功能。在ARM上,浮点曾经是可选的,但在没有FP的处理器上,可以可靠地捕获“无效的opertion”异常。如果您已链接FP仿真库,则可以接管并从异常中恢复。
更现代的方法是使用备用代码路径。只需编译可以从非常用指令中受益的每个函数的两个版本。在运行时,检查可用的CPU,并使用它来决定使用哪组函数。一种变化是将这些函数打包在两个DLL / .so中,并根据CPU加载其中一个。