Was ist die tatsächliche Auswirkung der Aufruf von socket."recv" - Vorgang mit einem bufsize, die nicht eine Potenz von 2 ist?
Zum Lesen von Daten von einem socket in python rufen Sie socket.recv
, die hat diese Signatur:
socket.recv(bufsize[, flags])
Den python-docs für die Steckdose.recv vage Zustand:
Hinweis: Für die beste übereinstimmung mit hardware-und Netzwerk-Realitäten, den Wert von
bufsize sollten eine relativ kleine
Potenz von 2, Z. B. 4096.
Frage: Was bedeutet "beste übereinstimmung mit hardware-und Netzwerk-Realitäten" bedeuten? Was ist die tatsächlichen Auswirkungen der Einstellung bufsize zu einem non-power-of-two?
Ich habe gesehen, viele andere Empfehlungen machen das Lesen eine Potenz von 2 ist. Ich bin auch sehr wohl bewusst, Gründen, wenn es ist oft nützlich, die array-Längen Zweierpotenzen (bitshift/Maskierung Operationen auf die Länge, die optimale FFT-array-Größe, etc), aber diese sind abhängig von der Anwendung. Ich bin nicht zu sehen, die Allgemeine Grund für es mit socket.recv
. Sicherlich nicht, um den Punkt der spezifische Empfehlung in der python-Dokumentation. Ich sehe auch nicht ein, alle power-of-two Optimierungen in der zugrunde liegende python-code zu machen, eine python-spezifische Empfehlung
Zum Beispiel... wenn Sie ein Protokoll, wenn das eingehende Paket die Länge genau bekannt ist, ist es natürlich vorzuziehen, nur Lesen "am meisten", was erforderlich ist für das Paket, die Sie zu tun, sonst könnten Sie möglicherweise Essen Sie in das nächste Paket und das wäre irritierend. Wenn das Paket ich bin derzeit auf der Verarbeitung hat nur 42 bytes anhängig, ich bin nur gehen, um bufsize 42.
Was bin ich? Wenn ich wählen Sie einen beliebigen Puffer - /array-Größe, die ich normalerweise (immer?) stellen Sie die Länge, die eine Potenz von zwei, nur für den Fall. Dies ist nur eine Gewohnheit, die im Laufe vieler Jahre entwickelt. Sind die python docs auch nur ein Opfer der Gewohnheit?
Dies ist nicht exklusiv für python, aber da bin ich insbesondere verweisen auf die python docs, ich werde tag, es als solches.
UPDATE: ich habe gerade überprüft die Größe des Puffers auf der kernel-Ebene auf meinem system (oder zumindest glaube ich ich habe... ich habe cat /proc/sys/net/core/rmem_default
) und es war 124928. Nicht eine Potenz von zwei. rmem_max
war 131071, auch eindeutig nicht eine Potenz von zwei.
In sich, in diese, mehr kann ich wirklich nicht sehen keinen nutzen in der Leistung von zwei-Empfehlung(en) noch nicht. Ich bin bereit, es zu nennen, wie eine falsche Empfehlung...
Habe ich auch noch tcp
und C
- tags, da Sie auch relevant sind.
- Meine beste Vermutung ist, dass einige OS-Ebene des Netzwerk-stacks können es vorziehen, halten power-of-2-Größe Puffer für Speicher-management-Gründe, aber dies scheint wie eine sinnlose historische Artefakt. Vielleicht der wichtigste Punkt der zu beachten ist, dass die Größe des Puffers sollte in der Größenordnung von 4 KB statt 4 MB oder 4 GB, und die power-of-2 ist nur Aberglaube.
- Meine Vermutung ist, dass das nur möglich ist, wirkliche Konsequenzen einer non-power-of-two Größe ist, dass einige der unteren Ebene, des Codes zuordnen können einem Puffer, dessen Größe ist die nächste Potenz von zwei ist sowieso, und der Letzte Teil, wenn der Puffer nicht gewöhnen. Nicht wirklich ein problem, es sei denn, Sie sind wahnsinnig kurz auf den RAM...
- Haben Sie einen Blick auf die Antworten auf in dieser Frage ALSO. Es befasst sich mit
recv()
zu und die Antworten können hilfreich sein für ein umfassenderes Verständnis. Es wird die Frage nicht beantworten, aber doch ein bisschen mehr Einblick. - Wahrscheinlich das einzige, das womöglich wichtige Nummern sind: cache-line-Größe (in der Regel 64 bytes, aber immer eine Potenz von 2 ist), und die Größe der Seite (in der Regel 4096 bytes, aber immer eine Potenz von 2 ist). Solange Sie ein Vielfaches von welche von denen ist mehr relevant, Sie sind wahrscheinlich ideal.
- Beachten Sie auch, dass aufgrund der cache-Verband Verrücktheit, es ist oft besser, nicht zu verwenden, genau eine Potenz von 2 ist.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich bin mir ziemlich sicher, dass die 'power of 2' Beratung beruht auf einem Fehler bei der Bearbeitung, und sollte nicht getroffen werden, als Anforderung.
Dass bestimmte Ratschlag war Hinzugefügt, um die Python 2.5-Dokumentation (und mehr auf Python 2.4.3 docs), in Reaktion auf Python-Problem #756104. Der reporter wurde mit einem unverhältnismäßig großen Puffer-Größe für
socket.recv()
, die Sie dazu aufgefordert werden das update.Es wurde von Tim Peters eingeführt, die der "power of 2" - Konzept:
(Fett-Hervorhebung von mir). Ich habe mit Tim, und er hat eine riesige Menge an Erfahrung mit Netzwerk, Programmierung und hardware, also generell gesprochen, würde ich ihm auf sein Wort, wenn so eine Bemerkung wie, dass. Er war besonders 'gern' von der Windows-95-stack, er nannte es seine canary in a coalmine für seine Fähigkeit, scheitern unter Beanspruchung. Beachten Sie aber, dass er sagt, ist es üblich,, nicht, dass es erforderlich Verwendung einer Potenz von 2.
War es, dass Formulierungen, die dann dazu geführt, dass die Dokumentation update:
Niemand bestritten die "power of 2' Behauptung hier, aber der editor verschoben aus ist es üblich zu sollte in den Raum von ein paar Antworten.
Mir, diejenigen die einen Vorschlag Einreichen der Dokumentation update waren mehr damit beschäftigt, mit der Herstellung sicher, dass du eine kleinen Puffer, und nicht, ob oder nicht es ist eine Potenz von 2 ist. Das ist nicht zu sagen, es ist nicht gut Beratung jedoch; keine low-level-Puffer, der interagiert mit dem kernel Vorteile, die mit der Angleichung an den kernel-Datenstrukturen.
Zwar, aber es kann gut sein, eine esoterische stack, wo die Puffer mit einer Größe, die eine Potenz von 2 Fragen noch mehr, ich bezweifle, Tim Peters überhaupt gemeint ist für seine Erfahrung (dass es gängige Praxis) umgewandelt werden in solche eiserne Bedingungen. Einfach ignorieren, wenn eine andere Puffergröße mehr Sinn macht, für Ihre spezifischen Anwendungsfälle.
In Bezug auf: "wenn Sie ein Protokoll, wenn das eingehende Paket die Länge genau bekannt ist, ist es natürlich vorzuziehen, nur Lesen "am meisten", was erforderlich ist für das Paket, die Sie zu tun, sonst könnten Sie möglicherweise Essen Sie in das nächste Paket und das wäre reizend."
Dies kann vorteilhaft sein, für die Anwendung Entwickler, aber ist wahrscheinlich ineffizient für die zugrunde liegende Netzwerk-stack. Erstens, es bindet socket-Puffer, die verwendet werden können für zusätzliche Netzwerk-I/Os. Zweitens, jeder recv (), die Sie machen, heißt eintauchen in ein system call/kernel-space und es ist eine performance-penalty für den übergang. Es ist immer vorzuziehen, um so viele Daten wie möglich aus dem kernel-space und in den user-space mit so wenig system-Aufrufe wie möglich und machen Sie Ihre Nachricht analysieren es. Dies fügt mehr Komplexität, um die Anwendung code und message-handling-ist aber wahrscheinlich auch der effizienteste.
Sagte, angesichts der Geschwindigkeit heutiger Prozessoren und der Menge des verfügbaren Speichers, dies kann nicht ein Problem für die meisten Anwendungen, aber dies war eine gemeinsame Empfehlung für Netzwerk-Applikationen zurück in den "alten Tagen".
Ich bin nicht sicher, über die Kraft von 2 Empfehlung von einem user-space-Anwendung. Ich habe gesehen, wie diese Typen die Anforderungen für die Fahrer aufgrund der Ausrichtung und Seitengröße Fragen, etc. aber es ist nicht klar, welche Auswirkungen dies hat aus user-space, es sei denn, es irgendwie aids in kopieren von Daten aus dem kernel-Puffer in Benutzer-Puffer. Vielleicht jemand mit mehr OS Entwicklung wissen konnte Kommentar.
bufsize
parameter hat nichts zu tun mit den zugrunde liegenden kernel-level socket-buffer.bufsize
ist nur die Größe des Puffers (ein python-string), zugewiesen ist, zu senden, um die kernel-recv Aufruf von Sachen, die gelesenen bytes in. ie:bufsize
sollte nicht "ineffizient für die zugrunde liegende Netzwerk-stack". Es ist hervorzuheben, dass, wenn Buchse.recv kehrt vorzeitig (langsam/patchily Ankunft eingehenden Daten??), der user-space-buffer allocation kann übermäßige. Ich habe die kernel-Puffer hat alle bytes, beschränkt es die kernel-recv Aufrufe zu einem, das ist schön.