PVM (Parallel Virtual Machine) ist ein Software Paket, das es einer heterogenen Menge von seriellen oder parallelen Computern, die an ein Netzwerk angeschlossen sind, erlaubt, als eine große Ressource zu erscheinen.
PVM ist ein einfach zu besorgendes "public-domain" Paket. Dieses Paket ist einfach zu installieren und zu konfigurieren. Großer Vorteil von PVM ist, daß viele virtuelle Maschinen nebeneinander auf der selben Hardware existieren können. Die Programmentwicklung wird unter Benutzung einer weit verbreiteten "Message Passing Library" unterstützt. Programme, die in PVM arbeiten sollen, können in Fortran oder C entwickelt werden. Die Installation von PVM benötigt nur wenige MB Platz auf den Festplatten. Die Migration von PVM zu MPI ist sehr einfach.
PVM bietet Unterstützung von Heterogenität auf drei Ebenen:
Auf Anwendungsebene bietet PVM Unterstützung in der Weise, daß Tasks
auf den Prozessoren im Cluster laufen, zu denen sie am besten passen. Auf Rechnerebene
werden verschiedene Datenformate, Architekturen, sowohl seriell als auch parallel,
und Betriebssysteme unterstützt. Auf Netzwerkebene stellt sich die Heterogenität
in so fern dar, daß eine Virtuelle Maschine sich über verschiedene
Typen von Netzwerken erstreclen kann, z.B. FDDI, Ethernet oder auch ATM.
PVM ist portabel, d.h. PVM ist inzwischen für eine breite Masse von Unix basierenden Computern verfügbar. Seit Version 3 von PVM kann die Virtuelle Maschine auch auf nicht-Unix Maschinen portiert werden, z.B. Windows basierende PCs. Es gibt auch Versionen von PVM für Supercomputer, z.B. Cray3.
PVM besteht aus sechs wichtigen Komponenten: den Task Identifiers (TID's), den Architecture classes, dem Message Model, der Asynchronous Notification, dem PVM Daemin und der Programming Library.
Die TIDs werden zur Adressierung von pvmd's, Tasks und Gruppen von Tasks benutzt. Die sind den Prozess-IDs unter Unix ähnlich. Die TIDs passen in den größten Integer-Datentyp (32 bit), der auf den meisten Maschinen zur Verfügung steht.
Die Felder S, G und H haben globale Bedeutung, d.h. jeder pvmd der virtuellen Maschine interpretiert diese Felder gleich.
Feld H enthält die relative Host-Nummer in der Virtuellen Maschine. Damit wird jedem pvmd ein eigener Adressbereich zugeordnet. Aus der Feldlänge und der relativen Adressierung ergibt sich aber auch eine Obergrenze für die Anzahl an Hosts in der Virtuellen Maschine, nämlich 2^12-1 Hosts.
Feld L ist für den privaten Gebrauch eines pvmds, wenn H mit der eigenen Host-Nummer gefüllt ist.
Feld G wird gesetzt, wenn Gruppen von Tasks angesprochen werden sollen
Feld S ist nur noch ein historisches Relikt und wird wohl dem H oder dem L Feld in der einer der nächsten Versionen zugesprochen werden.
Jeder Maschine in der Virtuellen Maschine wird eine Architektur Klasse zugeordnet. Damit wird eine Unterscheidung zwischen Maschinen, auf denen verschiedene ausführbare Programme auf Grund von Hardware oder Betriebssystem laufen, ermöglicht. Manchmal kann es trotz inkompatibler Programme doch selbe Repräsentation binärer Daten geben, hier ist dann keine Datenkonversion nötig. Dazu werden den Architektur Klassen sogenannte "data encoding" Nummern zugeordnet. Anhand der "data encoding" Nummern wird festgestellt, wann einer Konvertierung der übertragenen Daten nötig ist.
Folgende Architektur Klassen sind zur Zeit in PVM3 vorhanden:
AFX8 Alliant FX/8
ALPHA DEC Alpha/OSF-1
ALPHAMP DEC Alpha/OSF-1 / using shared memory
AIX46K IBM/RS6000 / AIX 4.x
AIX4MP IBM SMP / shared memory transport / AIX 4.x
AIX4SP2 IBM SP-2 / using MPI / AIX 4.x
APOLLO HP 300 running Domain/OS
ATT AT&T/NCR 3600 running SysVR4
BAL Sequent Balance
BFLY BBN Butterfly TC2000
BSD386 80[345]86 running BSDI or BSD386
CM2 Thinking Machines CM-2 Sun front-end
CM5 Thinking Machines CM-5
CNVX Convex using IEEE floating-point
CNVXN Convex using native f.p.
CRAY Cray
CRAY2 Cray-2
CRAYSMP Cray S-MP
CSPP Convex Exemplar
DGAV Data General Aviion
E88K Encore 88000
FREEBSD 80[345]86 running FreeBSD
HP300 HP 9000 68000 cpu
HPPA HP 9000 PA-Risc
HPPAMP HP 9000 PA-Risc / shared memory transport
KSR1 Kendall Square
I860 Intel RX Hypercube
IPSC2 Intel IPSC/2
LINUX 80[3456]86 running Linux
M88K Motorola M88100 running Real/IX
M88K Motorola M88100 running Real/IX
MASPAR Maspar
MIPS Mips
NETBSDAMIGA Amiga running NetBSD
NETBSDHP300 HP 300 running NetBSD
NETBSDI386 80[345]86 running NetBSD
NETBSDMAC68K Macintosh running NetBSD
NETBSDPMAX DEC Pmax running NetBSD
NETBSDSPARC Sparc running NetBSD
NETBSDSUN3 SUN 3 running NetBSD
NEXT NeXT
PGON Intel Paragon
PMAX DEC/Mips arch (3100, 5000, etc.)
RS6K IBM/RS6000 / AIX 3.x
RS6KMP IBM SMP / shared memory transport / AIX 3.x
RT IBM/RT
SCO 80[345]86 running SCO Unix
SGI Silicon Graphics IRIS
SGI5 Silicon Graphics IRIS running OS >= 5.0
SGI64 Silicon Graphics IRIS running OS >= 6.0
SGIMP Silicon Graphics IRIS / OS 5.x / usm
SGIMP64 Silicon Graphics IRIS / OS 6.x / usm
SP2MPI IBM SP-2 / using MPI / AIX 3.x
SUN3 Sun 3
SUN4 Sun 4, 4c, sparc, etc.
SUN4SOL2 Sun 4 running Solaris 2.x
SUNMP Sun 4 / using shared memory / Solaris 2.x
SX3 NEC SX-3
SYMM Sequent Symmetry
TITN Stardent Titan
U370 IBM 3090 running AIX
UTS2 Amdahl running UTS
UVAX DEC/Microvax
UXPM Fujitsu running UXP/M
VCM2 Thinking Machines CM-2 Vax front-end
X86SOL2 80[345]86 running Solaris 2.x
WIN32 PC's running Windows95 or NT (Intel, Alpha)
Pvmd's un Tasks können Nachrichten erzeugen und versenden. Diese Nachrichten sind von variabler Länge und enthalten typisierte Daten. Die Virtuelle Maschine besorgt die Konvertierung zwischen Hosts mit inkompatiblem Datenformaten. Nachrichten können beim Versand frei wählbar "beschriftet" werden. Der Empfang von Nachrichten ist nach Absender oder nach "Beschriftung" möglich.
Der Sender einer Nachricht bekommt vom Empfänger keine Bestätigung, dafür kann er sich aber darauf verlassen, das die Virtuelle Maschine die Nachricht zuverlässig verschickt, vorrausgesetzt, der Empfänger existiert. Die Tasks müssen also selbst dafür sorgen, daß Nachrichten, die zu Tasks gesendet wurde, die inzwischen zusammengebrochen sind, an andere Tasks zur Bearbeitung verschickt werden.
Die Virtuelle Maschine stellt Benachrichtigungen zur Verfügung. Damit ist eine gewisse Programmierung von Fehler-Toleranz möglich. Ein Task kann vom System eine Benachrichtigung über folgende drei Ereignisse anfordern:
Type Meaning ---------------------------------------------- PvmTaskExit Task exits or crashes PvmHostDelete Host is deleted or crashes PvmHostAdd New hosts are added to the VM ----------------------------------------------
In der Virtuellen Maschine exisitert auf jedem Host ein pvmd. Der pvmd eines Users interagiert nicht mit denen eines anderen, dadurch sind Sicherheitsrisiken minimiert. Der pvmd dient als Nachrichtenübermittler und Nachrichtencontroller. Für die Tasks ist er Kontaktpunkt, er übernimmt die Authentifizierung, Prozesskontrolle und die Fehlerüberwachung.
Der erste pvmd, der von Hand gestartet wird, ist der Master. Alle weiteren, vom Master gestaret, werden Slaves genannt.
Die Bibliothek libpvm dient als Schnittstelle zwischen Tasks und pvmd oder anderen Tasks. Die enthält Funktionen für das Erzeugen und das damit verbundene "packing" und das Empfangen und das damit verbundene "unpacking" von Nachrichten. Außerdem können Tasks durch sie sogenannte Service Anfragen (syscalls) an den pvmd stellen.
Die libpvm ist klein und schmal. Die obere Ebene enthält maschinen-unabhängigen Code. Die untere Ebene ist davon getrennt, die kann bei Portierung modifiziert oder duch maschinen-spezifischen Code ersetzt werden.
Ausgabe des Namens und der lokalen Zeit aller physikalischen Maschinen eines Clusters.
Als Modell wird das bekannte Master und Slave Modell gewählt. Der Master Prozeß wird als einziger vom User auf einer Maschine gestartet. Der Master Prozeß startet und kontrolliert die Slaves auf den anderen Maschinen.
Was muß der Master tun:
/* master program for the simple communication program */
/* which starts slaves just to get their names and the */
/* local time back */
#include <stdio.h>
#include <pvm3.h>
int main(void)
{
struct pvmhostinfo *hostp;
int result, check, i, nhost, narch, stid;
char buf[64];
pvm_setopt(PvmRoute, PvmRouteDirect); /* channel for communication */
gethostname(buf, 20); /* get name of master */
printf("The master process runs on %s \n", buf);
/* get and display configuration of the parallel machine */
pvm_config( &nhost, &narch, &hostp ); /* get configuration */
printf("I found the following hosts in your virtual machine\n");
for (i = 0; i < nhost; i++)
{
printf("\t%s\n", hostp[i].hi_name);
}
for (i=0; i<nhost; i++) /* spawn processes on */
{ /* all physical machines */
check=pvm_spawn("answer", 0,PvmTaskHost,hostp[i].hi_name, 1, &stid);
if (!check) printf("Couldn't start process on %s\n", hostp[i].hi_name);
}
result=0;
while (result>nhost)
{
pvm_recv(-1, 2); /* wait for reply message */
pvm_upkstr(buf); /* unpack message */
printf("%s\n", buf); /* print contents */
result++; /* next message */
}
pvm_exit; /* we are done */
}
/* slave program for PVM-first-try */
/* returns string consisting of machine name and local time */
#include <stdio.h>
#include <pvm3.h>
#include <time.h>
int main(void)
{
time_t now;
char name[12], buf[60];
int ptid;
ptid = pvm_parent(); /* the ID of the master process */
pvm_setopt(PvmRoute, PvmRouteDirect);
gethostname(name, 64); /* find name of machine */
now=time(NULL); /* get time */
strcpy(buf, name); /* put name into string */
strcat(buf, "'s time is ");
strcat(buf, ctime(&now)); /* add time to string */
pvm_initsend(PvmDataDefault); /* allocate message buffer */
pvm_pkstr(buf); /* pack string into buffer */
pvm_send(ptid, 2); /* send buffer to master */
pvm_exit; /* slave is done and exits */
}

Auf jedem Host muß das Slave-Programm (hier answer) im entsprechenden
Verzeichnis ($HOME/pvm3/bin/LINUX) vorhanden sein. Eventuelle muß
es für unterschiedliche Slaves neu compiliert werden.
[markus@HHCS015 LINUX]$ pvm
pvm> conf
conf
1 host, 1 data format
HOST DTID ARCH SPEED DSIG
HHCS015 40000 LINUX 1000 0x00408841
pvm> add mbs001
add mbs001
1 successful
HOST DTID
mbs001 80000
pvm> conf
conf
2 hosts, 1 data format
HOST DTID ARCH SPEED DSIG
HHCS015 40000 LINUX 1000 0x00408841
mbs001 80000 LINUX 1000 0x00408841
pvm> quit
quit
Console: exit handler called
pvmd still running.
[markus@HHCS015 LINUX]$ ./master
The master process runs on HHCS015
I found the following hosts in your virtual machine
HHCS015
mbs001
HHCS015's time is Sun Nov 18 14:57:19 2001
mbs001's time is Sun Nov 18 15:48:16 2001
[markus@HHCS015 LINUX]$