Wenn Sie ls
ohne Argumente arbeiten, wird lediglich ein Verzeichnis geöffnet, der gesamte Inhalt gelesen, sortiert und ausgedruckt.
Wenn Sie ausführen ls *
, wird zuerst die Shell erweitert. Dies entspricht im Grunde dem *
, was die einfache Shell ls
getan hat. Sie erstellt einen Argumentvektor mit allen Dateien im aktuellen Verzeichnis und ruft auf ls
. ls
Dann muss dieser Argumentvektor und für jedes Argument verarbeitet und access(2)
die Datei aufgerufen werden, um ihre Existenz zu überprüfen. Dann wird die gleiche Ausgabe wie die erste (einfache) ausgegeben ls
. Sowohl die Verarbeitung des großen Argumentvektors durch die Shell als auch die Verarbeitung des großen Argumentvektors durch die Shell ls
werden wahrscheinlich viel Speicherzuweisung für kleine Blöcke erfordern, was einige Zeit in Anspruch nehmen kann. Da es jedoch wenig war sys
und user
Zeit, aber viel real
Zeit, hätte man die meiste Zeit verbrachte für Disk warten, anstatt CPU Speicherzuweisung zu tun.
Bei jedem Aufruf von access(2)
muss der Inode der Datei gelesen werden, um die Berechtigungsinformationen abzurufen. Das bedeutet, dass viel mehr Datenträger gelesen und gesucht werden als nur ein Verzeichnis. Ich weiß nicht, wie teuer diese Vorgänge für Ihr GPFS sind, aber da der Vergleich, den Sie gezeigt haben, ls -l
eine ähnliche Laufzeit wie der Platzhalterfall aufweist, scheint die zum Abrufen der Inode-Informationen erforderliche Zeit zu dominieren. Wenn GPFS bei jedem Lesevorgang eine geringfügig höhere Latenz als Ihr lokales Dateisystem aufweist, ist in diesen Fällen eine stärkere Latenz zu erwarten.
Der Unterschied zwischen dem Platzhalter und ls -l
50% könnte durch die Reihenfolge der Inodes auf der Festplatte erklärt werden. Wenn die Inodes nacheinander in der gleichen Reihenfolge angeordnet würden wie die Dateinamen im Verzeichnis und ls -l
stat (2) die Dateien vor dem Sortieren in der Verzeichnisreihenfolge, ls -l
würden möglicherweise die meisten Inodes in einem Sweep gelesen. Mit dem Platzhalter sortiert die Shell die Dateinamen, bevor sie an sie übergeben werden ls
, sodass ls
die Inodes wahrscheinlich in einer anderen Reihenfolge gelesen werden und die Bewegung des Plattenkopfs verstärkt wird.
Es ist zu beachten, dass Ihre time
Ausgabe nicht die Zeit enthält, die die Shell zum Erweitern des Platzhalters benötigt.
Wenn Sie wirklich sehen möchten, was los ist, verwenden Sie strace(1)
:
strace -o /tmp/ls-star.trace ls *
strace -o /tmp/ls-l-star.trace ls -l *
und schauen Sie, welche Systemaufrufe jeweils durchgeführt werden.
¹ Ich weiß nicht, ob access(2)
tatsächlich etwas verwendet wird oder etwas anderes wie stat(2)
. Aber beide erfordern wahrscheinlich eine Inode-Suche (Ich bin nicht sicher, ob access(file, 0)
eine Inode-Suche umgangen werden würde.)
ls
man das Dateisystem einfach fragen kann "was sind die Kinder der Inode fürpwd
" woher wie mitls *
es muss fragen: "Was sind die Kinder (und was ist die Datei) der Inodea
", gefolgt von b, c, d usw. usw. Eine Abfrage gegen viele.