Linux 在科学实验室中的应用
我们的实验室,国家标准与技术研究院 (NIST) 中子研究中心 (NCNR),使用中子束探测材料的结构和性质。这项技术在许多方面类似于其更广为人知的亲属——X 射线散射,但在研究半导体、超导体、聚合物和混凝土等多种材料方面具有独特的优势。
如果没有计算机技术,我们的工作将无法完成。计算机帮助我们收集实验数据:它们与现实世界交互,控制和记录各种物理参数,如温度、通量和机械位置。收集到的测量数据需要显示、分析并传达给他人。所有这些阶段都需要复杂而灵活的计算机工具。在本文中,我们将描述 Linux 如何帮助我们解决日常工作中出现的许多需求。我们相信,我们的经验对于任何科学或工程研究和开发实验室都可能具有代表性。
我们从使用 Linux 中获得的主要优势是其惊人的灵活性。由于开放的开发模式和开源代码,没有“黑盒”子系统;当某些东西不能正常工作时,我们通常可以调查问题并将其修复到我们满意的程度。Linux 中存在的重要的合作和互助精神对我们很重要——这是开放软件的普遍理念以及源代码可供任何人修复的实际结果。此外,Linux 相当健壮,从某种意义上说,一旦设置好,它就会保持设置状态;Linux 没有我们不幸地学会期望从主流计算机操作系统中看到的那种脆弱性。
不幸的是,有时我们遇到对某些有用的硬件或软件缺乏支持的情况。由于很少有制造商积极支持 Linux,Linux 上的驱动程序可用性落后于 Windows 95,尽管由于许多贡献其硬件驱动程序的人的出色工作,它可能优于任何其他环境。我们通过在购买前检查驱动程序的可用性,并远离不发布其产品工程规范的制造商来避免不支持的硬件。
最终,我们使用任何能更好地完成工作的环境。由于某些工具在 Windows 上可用而不在 Linux 上可用,我们有时会使用前者。例如,Windows 上可用的 LabView 软件是一个集成的图形工具,用于快速构建数据采集原型,并拥有令人印象深刻的仪器硬件驱动程序集合。它有时是首选平台,尤其是在探索性工作方面,尽管它在处理更复杂的任务时扩展性不佳。
总的来说,我们大约有 25 台计算机运行 Linux。我们对它们的运行非常满意,并在过程中为纳税人节省了一大笔钱。我们已经看到 Linux 从一个几乎不为人知、被认为有风险且缺乏支持的系统,发展到目前的地位,成为品牌 UNIX 和 NT 机器的有力竞争者,我们肯定看到了 Linux 的未来。
现实世界的数据采集通常需要无休止地重复高精度测量,因此非常适合计算机,只要数据以计算机可读的形式提供。不幸的是,数据采集不是大众市场应用,因此采集硬件往往昂贵且难以获得,即使对于无处不在的 PC/x86 平台也是如此。以声卡为例:它具有高质量的模数和数模转换器、定时器、波表内存等,所有这些都只需大约 100 美元。类似的硬件,只需进行相对较小的修改使其适合数据采集,可能需要花费大约 1000 美元。
我们在 NCNR 使用的科学仪器本身就非常多样化和有趣;即使在计算机介入之前,也涉及大量的机械和电子工程。我们的一些仪器在尺寸和重量上都非常惊人——我们实际上使用退役的战列舰炮塔组件来支撑它们。您可以通过查看图 1 和图 2 来感受我们仪器的规模;实验大厅的尺寸约为 30 米 x 60 米。
就本文而言,让我们假设设计和构建仪器的所有艰苦工作已经完成,包括提供适当的传感器来测量感兴趣的物理量,如温度、辐射强度或位置。我们的任务是将来自这些传感器的数据读入计算机。(由于对硬件成本和可用性的担忧,PC/x86 平台是数据采集任务的实际选择。)
最简单且非常常见的情况是仪器具有内置串行端口。然后我们可以使用常规串行通信与其通信,就像与调制解调器通信一样。我们实验室中此类仪器的示例包括步进电机控制器、温度控制器和各种精确的时间测量设备。
串行线路 (RS-232) 接口的简单性是有代价的:串行连接速度相当慢,不适合需要快速响应或大量数据的情况。它还具有一个令人讨厌的特点,即它是一个非常松散定义的标准。存在许多变体:DTE 与 DCE 配置;硬件与软件握手;数据、停止和奇偶校验位的各种设置。由于有如此多的可能性,两个随机选择的设备在插入电缆后立即相互通信的可能性非常小。“分线盒”在这里很有用:它是一个与我们的串行电缆串联连接的小型外壳,显示数据线的状态,并允许我们使用跳线重新路由各个信号线。
与弄清楚正确的布线和通信参数的难度相比,串行端口通信的实际编程非常简单,因为 Linux 已经提供了高质量的串行端口驱动程序。(当然,Linux 不依赖于 PC BIOS 和 MS-DOS 中的串行端口例程,因为它们太不充分了,以至于创建了一个完整的家庭手工业来提供所谓的“通信库”。)
串行端口通信的一个问题:RS-232 本质上是一个点对点链路——没有标准且可靠的方法将多个设备连接到同一串行线路。有一种方案是将多个设备菊花链式连接,即计算机的发送线连接到设备 1 的接收输入,其发送线连接到设备 2 的接收输入,依此类推,直到最后一个设备的发送线返回到计算机的接收引脚。这要求所有设备通过传递并非针对它们的数据来协作;当链中可能存在来自设备的异步响应时,它也不可靠。PC 平台上通常提供的两个标准串行端口之一被鼠标占用,因此如果我们需要多条串行线路,则需要多端口扩展板。幸运的是,Linux 内置了对几种廉价多端口板的支持。我们使用过 Cyclades 和 STB 板;它们非常容易配置,并且它们的驱动程序以常规串行端口的形式呈现给程序员。
对于初始探索和测试,我们通常使用 Seyon 或 Kermit 终端仿真器。Seyon 随大多数 Linux 发行版一起提供,而 Kermit 必须从哥伦比亚大学的 FTP 站点获取,因为其许可条款禁止第三方分发。minicom 程序更难配置,因此我们不太使用它。
Nick 编写了一个工具命令语言 (Tcl) 串行通信扩展,用于灵活的串行端口 I/O,具有超时和终止符字符。Tcl 非常适合我们的环境,因为它可以方便地嵌入为重型 FORTRAN 和 C 程序的脚本工具,并且它允许快速开发,同时足够健壮,可以部署在生产环境中。我们将在本文后面讨论脚本在我们环境中的好处。
另一种在科学和工程界流行的硬件接口是 GPIB——通用接口总线。它由惠普公司设计和推广(因此其原名 HP-IB),后来成为官方行业标准 IEEE-488。它是一种中速并行总线,能够实现超过 100Kbps 的带宽。许多科学仪器都支持它,并且惠普、美国国家仪器公司和其他公司生产了相对便宜的 PC 控制器。幸运的是,Claus Schroeter 编写的 Linux 内核驱动程序已经存在于大多数常见的 GPIB 卡中。(请参阅 Timotej Ecimovic 的《GPIB:酷,它可以在 Linux 上工作》,《Linux Journal》,1997 年 3 月。)
对于那些需要非常快速数据传输的应用,VME 总线是一个常见的选择。VME 在电信行业以及工业和军事测试和测量应用中很受欢迎。它通常安装在大型(且昂贵的)背板机箱中,其中包含 24 个卡槽。通常,其中一个插槽被控制器占用,该控制器控制其余插槽中的 I/O 模块。最初,VME 被设计为与摩托罗拉 68k 系列 CPU 一起工作,因此大多数机箱控制器都是基于 68k 的,但最近基于 PowerPC 甚至 Pentium 的控制器似乎更受欢迎。
事实证明,所有这些架构都有 Linux 端口,但同样,对我们来说最简单的是使用基于 x86 的 VME 控制器。在大多数方面,它是一个标准的 Pentium/PCI 迷你主板,唯一不寻常的特性是板载 PCI-VME 桥接芯片。我们使用 VMIC 制造的带有 VIC 桥接芯片组的控制器;Nick 基于我们在网上找到的另一个 VME 桥接驱动程序为其编写了一个驱动程序。
所有 VME I/O 都是通过内存映射完成的。I/O 模块通过读取和写入其特定的内存位置来访问;需要 VME 桥接芯片将 CPU 本机总线周期转换为 VME 总线。程序只需映射适当的内存区域(使用 mmap),然后就可以执行常规的内存加载和存储操作来访问 VME 外围设备。
我们目前正在完成一个大型数据采集系统,该系统收集来自 800 多个探测器观察到的事件的精确计时信息。我们设计了一个 VME 卡模块上的前端处理器,该处理器处理 32 个探测器,以及另一个模块,该模块将来自这些前端模块的数据多路复用到机箱控制器中。由于此应用中最大可能的数据速率为每秒 300,000 个事件,因此 VME 是一个合适的平台。
PLC 广泛应用于工业过程控制环境。(请参阅 J. P. G. Quintana 在《Linux Journal》,1997 年 1 月发表的《在可编程逻辑控制器中使用 Linux》。)它们是基于继电器的控制系统的后代,由专用微控制器控制的模块化 I/O 块构建而成。可用的模块包括数字和模拟 I/O、温度控制、运动控制等。它们以简单性和低速度换取低成本和工业级可靠性;它们的机械集成也非常好——各个模块可以弹出到安装导轨中,并且可以轻松安装和拆卸。市场上有几种 PLC 系统;我们目前使用 KOYO 产品。
通常,简单的控制程序是在专有的交叉编译环境(通常以继电器“梯形图”的形式,这是一种可以追溯到机电继电器时代的方法)中开发的,并通过串行链路下载。通常这些程序在 Windows 下运行,但它们只需要在开发时运行。将控制程序存储在闪存中后,微控制器通过内置串行链路与我们的 Linux 盒通信,发送数据和接收命令。
图 2. 我们的一个实验站,左侧是仪器控制计算机,以及两个 VME 机箱和一个 PLC 单元。Linux 在 PC 和较低 VME 机箱的控制器中运行。
并行端口提供了另一种流行的计算机接口。正如 Alessandro Rubini 在《使用打印机端口进行网络连接》(《Linux Journal》,1997 年 3 月)中解释的那样,并行端口基本上是一个数字 I/O 端口,具有 12 个输出位和 4 个输入位(实际上,最近增强的并行端口实现也允许 12 个输入位)。对于一位敬业的业余爱好者来说,这是一项宝贵的资源,可以驱动各种设备(D/A 和 A/D 转换器、频率合成器等);不幸的是,一台计算机中通常只有一个这样的端口,并且它往往被打印机不方便地占用。串行端口也可以以非标准方式使用;其状态线可以独立控制,因此提供几个数字 I/O 位。
这种数字 I/O 可用于将信息“位bang”到串行总线设备,如 I2C 微控制器。(I2C 是一种双线串行协议,用于某些嵌入式微控制器,有时甚至在消费产品中也可用。)
USB 是另一种类型的接口,在可用硬件和 Linux 支持方面都出现了。虽然 USB 是为键盘、鼠标或扬声器等外围设备设计的,但它速度足够快,可以用于某些数据采集目的,并且一些制造商已经宣布了该领域的未来产品。USB 的一个优点是 USB 连接器可以提供有限的电量,从而无需为外部设备提供额外的电源线。
随着硬件成本的降低以及 Linux 提供的灵活性,我们一直在计划使用分布式硬件控制。我们可以部署多台精简的计算机(硬件服务器),配备网卡但没有键盘或显示器,而不是让一台工作站连接到所有外围设备。这些服务器中的每一台都将与硬件子集通信,执行主控制工作站(控制客户端)通过网络发送的命令。对于服务器,我们可以使用较旧的回收的 486 级机器,甚至可以使用行业标准的 PC-104 模块(一种微型 PC 格式,由尺寸约为 10 厘米 x 10 厘米的可堆叠模块组成)。在这种情况下,以太网成为我们的现实世界接口。
当然,我们也已将 Linux 用作更传统的通用图形工作站。在这里,我们不再局限于 x86 架构。由于我们不必处理硬件问题,因此我们可以选择多个平台,包括 Digital 的基于 Alpha 的计算机。目前(1998 年 2 月),可以以略高于 2000 美元的价格购买一台 533MHz Alpha 工作站;价格似乎在下降,而时钟速度正在上升到传闻中的 800MHz 范围。Alpha Linux 已为价格非常低的严肃计算做好准备。Alpha 是一款出色的执行者,尤其是在浮点计算方面——SPEC 基准测试显示,稍微慢一点的 500MHz Alpha 的整数计算速度 (SPECint95) 为 15.7,浮点计算速度 (SPECfp95) 为 19.5。相比之下,233MHz 的 Pentium II 的 SPECint95 为 9.49,SPECfp95 为 6.43,是 Alpha 芯片浮点性能的三分之一。
自 1995 年以来,我们一直在使用基于 Linux 的 PC 工作站。它们通常只是作为我们部门计算机服务器的功能强大的远程客户端,以低于某些商业 X 终端的价格提供更好的 X 终端功能,并用于轻型本地办公计算。然而,我们越来越多地使用它们来执行本地计算。我们目前正在考虑的一个有趣的项目是为此处经常执行的某种计算(非线性拟合)安装联网服务器进程,并将并行计算分发到当前未被其他客户端使用的服务器。由于平均个人计算机的大部分周期都花在等待用户按键上,因此我们计划有利可图地利用这些空闲周期。
当然,这种方法的灵感来自 Beowulf 集群项目,其中 Linux 盒的集合通过专用快速网络互连,以运行大规模并行代码。(请参阅 Jim Hill、Michael Warren 和 Pat Goda 的《我不会为这台超级计算机支付很多钱!》,《Linux Journal》,1997 年 1 月。)华盛顿特区地区有几个 Beowulf 安装,包括 Donald Becker 在 NASA 的原始站点以及国家卫生研究院的 LOBOS 集群。相比之下,我们计划使用非专用硬件,通过通用网络连接。我们可以摆脱困境,因为我们的情况不需要太多的进程间通信。
不幸的是,我们没有太多空间来讨论科学可视化;这是一个在科学和美学上都引人入胜的领域;它涉及现代 3-D 图形技术,并且一些图像非常漂亮。计算机可视化是一个新兴领域,因此开发工具与最终用户应用程序一样重要。在我们看来,图形的最佳环境由 OpenGL 环境提供。OpenGL 是 Silicon Graphics 为其高性能图形系统设计的编程 API,它开始出现在 Windows 上;在 Linux 上,一些商业 X 服务器支持它。此外,Mesa 是 OpenGL 的免费实现,它在 X 之上运行,并在 Linux 上提供 OpenGL。这涉及一种权衡——在没有高端图形硬件和匹配的 OpenGL 实现提供的硬件辅助的情况下,3-D 图形会明显变慢,但是 X 窗口系统不与任何特定终端绑定的优势非常重要。
在 Mesa/OpenGL 的基础上,有许多出色的可视化程序和工具包,其中一些在 Mesa 页面中引用。特别是,VTK 可视化小部件及其随附的书籍值得一提。另一个应用程序是 GeomView,这是一个用于显示几何对象的通用引擎,由明尼苏达大学几何中心编写。
我们发现脚本软件方法对于科学计算和数据采集都非常有用。脚本是一种编写软件的风格,在这种风格中,我们不是构建具有硬连线控制流的单片程序,而是通过将代码划分为执行部分工作的模块来重构代码。为了将这些模块粘合在一起,我们使用命令行解释器编译它们。
高级语言 (HLL) 解释器已经存在很长时间了(Scheme、Basic、Perl、Tcl、Python),但直到最近才强调将它们嵌入到用户的程序中。即使没有这种嵌入,解释器对于原型设计仍然有用,但对于较大的项目,它们往往会耗尽精力。关键是将解释系统的灵活性与编译后的 HLL 代码的速度和功能结合起来。
例如,让我们想象一个程序,该程序打开并处理配置文件,要求用户输入并计算一些结果。传统上,此类程序的控制流硬连线在其主例程中;每个 I/O 阶段都单独编程,每个阶段的数据都有单独的语法。(配置文件可能是一个数字表,用户输入可能具有表示命令的简单 ASCII 字符串的形式。)
为了以脚本风格重写此程序,我们将把配置和计算阶段重铸为由脚本解释器调用的单独模块。工作模块的数据将保存在解释器的变量中,而 I/O 将由解释器的本机设施处理。为了完成程序,我们必须编写一个简短的解释器脚本,该脚本读取配置文件,存储和处理值,获取用户输入,启动计算并输出结果。重要的一点,也是需要一段时间才能习惯的一点是,程序中不再有硬连线的控制流:当它启动时,解释器接管并等待脚本(来自命令行或脚本文件)来启动模块。
在几种现代脚本语言中,我们选择使用 Tcl/Tk。其他语言,如 Python 和 Perl,同样优秀,并且具有类似的功能。我们编写了大量的 Tcl 扩展,处理平台独立的自描述数据文件、二进制数据矩阵和图像处理、算术表达式等抽象。
脚本方法有几个好处。首先,它提供了更大的灵活性:更改解释脚本以执行两轮计算而不是一轮计算将是微不足道的。此外,将用户界面代码与计算代码分离要容易得多——添加 GUI 数据输入所需做的只是重写脚本的用户界面部分,使其使用解释器的 GUI 小部件。
其次,解释器通常提供通用的语言结构,例如宏/过程以及循环和条件语句。这使得编写复杂而灵活的批处理脚本成为可能。
请注意,正确设计的可脚本化应用程序调和了命令行和基于 GUI 的程序之间人为且不必要的区别。图形用户界面背后的前提是为所有操作提供视觉提示;然而,权衡通常是其他操作(没有包含 GUI 元素的操作)是不可能的。换句话说,GUI 承诺“所见即所得”的操作,但它通常提供“你得到的就是你得到的”。
使用脚本,GUI 被设置为调用预定义的命令列表;同时,可以指示解释器接受用户键入的命令或文件输入,从而允许任意命令序列。能够使用文件选择器对话框选择文件很好,但是任何必须为一百个文件协商此类文件选择的人都必须欣赏在命令行上键入 process *.dat 的实用性。
可扩展脚本语言的最终好处是它非常适合为复杂对象或操作创建抽象。这种抽象之所以好,有两个原因:它们使复杂的操作更容易理解和执行,同时它们也实现了高性能,因为它们是编译后的扩展。一个很好的例子可能是 BLT,我们经常使用的 Tcl 图形扩展。它是一个复杂的图形工具,具有数十个选项。其复杂的内部结构被简单地封装:高级选项可用,但不必使用。简单绘图所需的一切是为绘图的 X 和 Y 坐标提供值。同时,由于它是 Tcl 的编译扩展,BLT 享有相当好的性能,即使在大型绘图上,也堪比完全用 C 编写的可视化工具。
由于共享库和扩展的动态加载,只需加载 BLT 包即可使用图形功能增强现有程序。这会在 Tcl 解释器中创建新的 graph 命令,然后可以在构造 GUI 的脚本中使用该命令。
在我们工作中多个地方出现的另一个有用的软件抽象是数值数组。此类数组在科学中极其重要:它们可能包含数据向量、几何坐标、矩阵等。标准 HLL 通常具有此类数组的概念,但它通常是二等公民对象。数组为数据存储提供空间,但无法像对简单的标量变量那样对它们执行中缀算术运算。此类语言中的数组处理一次完成一个元素,这对于大型矩阵来说速度非常慢(请参见下面的示例)。(当然,FORTRAN90 和带有适当矩阵代数库的 C++ 允许为矩阵以及标量变量编写像 A*B 这样的计算,但这些环境在 Linux 或商业平台上都不常见。)
用于进行矩阵乘法的典型 C (HLL) 代码如下:
for( i=0 ; i<N ; i++) for( j=0 ; j<N ; j++) for( k=0 ; k<N ; k++) C[i][j] = A[j][k] * B[k][i] } } }
对于 Matlab/Octave (VHLL),代码如下所示:
C = A * BVHLL 代码显然更容易编写。此外,在解释性语言中,循环迭代是逐个解释的;在 VHLL 中,整个操作以机器代码全速执行。
术语“超高级语言”指的是此类特定于问题领域的语言。对于数值计算,有一种商业 VHLL 称为 Matlab。它为数值数据的计算和显示提供了复杂的环境,并将数组变量作为一等公民对象。它是一个非常好的工具包,并且在 Linux 上受支持。有趣的是,Matlab 有一个名为 Octave 的免费克隆,它提供了其大部分功能;Matlab 代码通常在 Octave 中不变地运行。(请参阅 Malcolm Murphy 的《Octave:一种免费的数学高级语言》,《Linux Journal》,1997 年 7 月。)这些系统令人上瘾;一旦你使用它们一段时间,就很难回到 FORTRAN。
以上评论在任何 OS 平台上都同样适用,无论是不同风格的 UNIX 还是甚至在 Windows 或 Macintosh 上。但是,Linux 提供了最完整的软件开发环境。各种本机脚本系统存在于各个平台上:Windows 上的 Visual Basic,Macintosh 上的 Hypercard 和 Metacard;然而,商业产品永远不完整。例如,Visual Basic 需要单独的 C 编译器来创建二进制扩展。另一方面,Linux 开箱即用地提供了所有工具(Tcl/Tk 库和头文件、GCC 编译器等)。
Przemek Klosowski 是一位在国家标准与技术研究院工作的物理学家。自从 13 年前偶然接触互联网,6 年前接触 Linux,4 年前创立华盛顿特区 Linux 用户组以来,他开始觉得自己像个老古董。他对 Java 感到不兴奋,更强化了这种感觉。尽管如此,Linux 和他支持有时也为其做出贡献的其他开源软件计划的成功,仍然保持着他的青春热情。您可以通过电子邮件 przemek@nist.gov 与他联系。
Nick Maliszewskyj 是马里兰州盖瑟斯堡 NIST 中子研究中心的物理学家,他在那里喜欢玩那里的大玩具。他目前的任务是编写软件,让一大群其他人也可以玩这些玩具。在非二进制世界的活动包括合气道、房屋维修、惊讶地看着他 3 岁的儿子以及为第二个孩子的到来做准备。您可以通过电子邮件 nickm@nist.gov 与 Nick 联系。
Bud Dickerson 一直为物理学家工作,因为他们让他玩酷玩具。然而,他晚上睡得太好了,以至于他对 Linux 的了解不如他所了解的。您可以通过 bud.dickerson@nist.gov 与他联系。