Chris Siebenmann blickt zurück, wie der Unix-Load-Average, im 3BSD-Zeitalter mit Ein-CPU-Maschinen noch simpel, mit Mehrprozessorsystemen und Threads vor drei Designfragen stand.

Die erste Frage: Auf einer Maschine mit vier CPUs und zwei dauerhaft laufenden Prozessen ist der Load-Average 2 oder 0,5? Moderne Unixe zählen lauffähige Prozesse global, die Antwort ist also 2, unabhängig von der CPU-Zahl. Irix normierte anfangs auf die Kapazität, sodass die Zahl auf jeder Maschine ungefähr denselben Auslastungsgrad bedeutete. Diese Variante setzte sich nicht durch. Heute braucht man neben dem Load-Average auch die CPU-Zahl, um eine Überlastung zu beurteilen.

Die zweite Frage ist die Thread-Zählung. Der Kernel sieht weder Green Threads noch User-Level-Threads, die auf weniger Kernel-Objekte gemultiplext werden. Frühe Implementierungen zählten daher nur, was der Kernel kannte, teils nur Prozesse, nicht Threads. Linux machte Threads zu einer Form von Prozessen, damit sind sie voll sichtbar. Das Problem lebt in Laufzeitumgebungen wie Go fort: Der Load-Average zeigt aktive OS-Threads, nicht die Zahl wartender Goroutinen.

Die dritte Frage betrifft, was über lauffähige Prozesse hinaus zählt. Der ursprüngliche 3BSD-Load-Average schloss Prozesse ein, die auf Platten-IO warteten, und kommerzielle Unixe wie das von Sun kopierten das, wobei NFS-IO als Platten-IO galt. Brendan Greggs Untersuchung von 2017 zeigte, dass Linux IO-Wartezeiten zunächst ausklammerte, aber sehr früh hinzunahm. Die BSDs variieren in diesem Punkt.