Η πρώτη (first) χρήσιμη (useful) ανάγνωση (read) (σ)ενός αναλυτή (parser) PDF βρίσκεται (is) (στη) στη (στη) λάθος (wrong) άκρη (end) του αρχείου (file). (Η) Το format βάζει (puts) (το) τον (το) δείκτη (pointer) startxref στα (in the) τελευταία (final) bytes, οπότε η επεξεργασία (processing) (ε)ενός αρχείου (archive) 1.8 GB ξεκινά (begins) με (with) μια αναζήτηση (seek) στην (to the) ουρά (tail), (μ)μια (μια) (ένα) ανάγνωση (read) (ε)ενός kilobyte, (και) (έπειτα) έπειτα (έπειτα) (ένα) ένα άλμα (hop) στο (to) σημείο (wherever) που ο πίνακας (table) διασταυρούμενων αναφορών (cross-reference) λέει (says) (ότι) ότι (ότι) ζει (lives) ο (the) κατάλογος του εγγράφου (document catalog). Από (From) (ε)εκεί (there) (η) η ανάλυση (parse) είναι (is) ένας (a) τυχαίος (random) περίπατος (walk) (σ)σε (σ)όλο το (the whole) εύρος (range) των (byte). (Ό)Όλα όσα (Everything) το προσωρινά αποθηκευμένο (buffered) (ή) (η) IO (είναι) (κάνει) κάνει (κάνει) καλά (good at) — (—) η διαδοχική (sequential) (προ)ανάγνωση (read-ahead) (π)πίσω από (behind) τον (the) δείκτη του αρχείου (file pointer) — (—) (στοχεύουν) στοχεύουν (στοχεύουν) σε (at) έναν (a) φόρτο εργασίας (workload) που (το) το (το) PDF δεν (does not) έχει (have)
Η (The) πρώτη (first) έκδοση (version) (α)αυτού του άρθρου (this article) ισχυριζόταν (claimed) (ότι) (ότι) (ότι) ένα (a) (ένα) (χαρτογραφημένο στη μνήμη) αρχείο χαρτογραφημένο στη μνήμη (memory-mapped file) (λ)λύνει (solves) (τ)την (τ)την 32-bit (32-bit) αποτυχία (failure) (λόγω) εξάντλησης (εξάντλησης) (από) μνήμης (out-of-memory) που (that) (η) η TMemoryStream χτυπά (hits) σε (on) μια είσοδο (input) (τ)των 2 GB. (Α)Αυτός ο (Αυτός ο) (Α) (Ο) ισχυρισμός (claim) είναι (is) λάθος (wrong), (κ)και ο (και ο) (κ) (και) τρόπος (way) που (που) (που) (είναι) (είναι) είναι (είναι) λάθος (wrong) (δ)δείχνει (points) στην (at the) (πραγματική) πραγματική (πραγματική) (τ)διόρθωση (fix): (ένα) ένα (ένα) ολισθαίνον (sliding) παράθυρο χαρτογράφησης (mapping window). (Α)Αυτό που ακολουθεί (What follows) είναι (is) (τ)το (τ)μοτίβο πρόσβασης (access pattern), η (the) (δ)διορθωμένη (corrected) 32-bit (32-bit) ιστορία (story) με (with) έναν (a) λειτουργικό (compilable) mapper (mapper) (μ)με (μ) (ε)παράθυρα (windowed), και (and) (η) (η) η κλήση συστήματος (syscall) (κ)αριθμητικής (arithmetic) (σ)σε ένα (ένα) (α)αρχείο δοκιμής (test file) 1.8 GB, 300,000 αντικειμένων (objects)
Γιατί η διάταξη (layout) του PDF νικά (defeats) τις (buffered) αναγνώσεις (reads) που χρησιμοποιούν buffers (buffered)
Τρία δομικά γεγονότα (structural facts) διαμορφώνουν (shape) το μοτίβο (pattern) IO. Πρώτον, η πλοήγηση (navigation) καθοδηγείται από offset (offset-driven): ο πίνακας (table) cross-reference χαρτογραφεί (maps) (κάθε) κάθε αριθμό (number) αντικειμένου (object) σε μια απόλυτη (absolute) θέση (position) (byte), (και) και τίποτα δεν (nothing) (α)απαιτεί (requires) αυτές οι θέσεις (positions) να (να) (είναι) (διατάσσονται) (παρατάσσονται) (είναι) ταξινομημένες (ordered). (Μετά από) (Μετά) (Μ)Μετά από (Μ)χρόνια (years) αυξητικών (incremental) ενημερώσεων (updates), το αντικείμενο 4102 (μ)μπορεί να (μπορεί) (κάθεται) κάθεται (κάθεται) (στ)στο (στο) (σ)offset 1.6 GB ενώ το αντικείμενο 4103 κάθεται στα 30 KB. Ένας (A) TFileStream βρόχος (loop) (μ)μετατρέπει (turns) (κάθε) κάθε άντληση (fetch) σε (into) ένα Seek (συν) συν (συν) (ένα) (ένα) (ένα) ένα Read, (δ)δύο μεταβάσεις πυρήνα (kernel transitions), με (with) (ένα) ένα (ένα) (τ)buffer (που) που (που) δεν (δεν) (δεν) συνεισφέρει (contributes) τίποτα (nothing) επειδή η επόμενη άντληση (fetch) βρίσκεται (is) (ε)εκατοντάδες (hundreds) (μ)megabytes μακριά (away)
Δεύτερον, τα (τα) (οι) αντικείμενα (object) ροής (streams) (ISO 32000-1 §7.5.7) (π)πακετάρουν (pack) (δ)δεκάδες (dozens) ή εκατοντάδες (hundreds) μικρά (small) (λ)λεξικά (dictionaries) (σε) σε έναν (one) (απο)συμπιεσμένο (deflated) (π)περιέκτη (container). Η (Fetching) άντληση (Fetching) (ενός) ενός (ε)λεξικού σελίδας 300-byte μπορεί (can) (ν)να σημαίνει (mean) την ανάγνωση (reading) και (and) την (inflating) (απο)συμπίεση (inflating) μιας (μιας) συστάδας (cluster) 100 KB. (Η) (Η) (Η) Η άλλη όψη (flip side): τα αντικείμενα που (που) (γ)γράφονται (written) μαζί τείνουν να (tend to) (δ)διαβάζονται (read) μαζί, οπότε ένα buffer προσαρμοσμένο (sized) (στ)στη (στη) (σ)συστάδα (cluster) εξυπηρετεί (serves) (τις) (τ)τις επόμενες (next) δώδεκα (dozen) (α)αντλήσεις (fetches) δωρεάν (for free) — (—) η πιο εκμεταλλεύσιμη (exploitable) (κ)κανονικότητα (regularity) στο (στο) (σ)στο (το) format
Τρίτον, η γραμμικοποίηση (linearization). Ένα (A) γραμμικοποιημένο (linearized) αρχείο (file) βάζει στην αρχή (front-loads) την (the) πρώτη (first) (σ)σελίδα (page) και έναν (and a) (π)πίνακα (table) (υ)υποδείξεων (hint) (ώ)ώστε (ώστε) οι (οι) καταναλωτές (consumers) να (να) μπορούν να (να) (το) (το) διαβάσουν (read) από (από) (ε)εμπρός (front) προς (προς) τα (τα) πίσω (back). Τα αρχεία (archives) Gigabyte (Gigabyte) σχεδόν ποτέ δεν (almost never) είναι γραμμικοποιημένα: η γραμμικοποίηση καταστρέφεται (destroyed) (α)από τις (τις) (ι)ίδιες (same) (α)αυξητικές (incremental) (ε)ενημερώσεις (updates) (κ)και (και) συγχωνεύσεις (merges) (π)που έκαναν (made) (τ)το αρχείο (το αρχείο) (το) (μεγάλο) (μ)μεγάλο (μεγάλο). Προγραμματίστε (Plan for) για τη (τη) (την) (ε)εχθρική (hostile) (π)περίπτωση (case): (μ)μακρινά (long) (ά)άλματα (hops), (κ)καμία (no) διάταξη (ordering), είσοδος (entry) (α)από την (την) (ο)ουρά πρώτα (tail-first)
Η 32-bit ιστορία (story), (δ)διορθωμένη (corrected)
Μια (A) (32-bit) διεργασία (process) 32-bit των Windows (Windows) (έ)έχει (έχει) 2 GB (2 GB) χώρου διευθύνσεων χρήστη (user address space), και η (and) MapViewOfFile με (με) πλήθος (count) (byte) byte ίσο με (ίσο) μηδέν (zero) (ζητά) (ζητά) ζητά (ζητά) (μια) μια (μια) συνεχόμενη (contiguous) δέσμευση (reservation) (ίση με το) ίση με το (ίση με το) μέγεθος του αρχείου. Για (Για) (μια) μια είσοδο (input) (2 GB) 2 GB αυτή η (this) (δ)δέσμευση (reservation) δεν (cannot) (μ)μπορεί να επιτύχει (succeed): μετά (after) το EXE, (τα) τα (δ)διάσπαρτα (scattered) DLLs, (κ)και τις στοίβες νημάτων (thread stacks), το (the) μεγαλύτερο (largest) (ε)ελεύθερο (free) συνεχόμενο (contiguous) μπλοκ (block) σε (σε) (μια) μια τυπική (typical) διεργασία Delphi (Delphi) 32-bit (32-bit) κάθεται (sits) (κ)κάπου (somewhere) ανάμεσα (between) στα 700 MB και 1.4 GB. Η (Η) κλήση αποτυγχάνει (fails) με (με) ERROR_NOT_ENOUGH_MEMORY, (τ)τον (τ)ίδιο τοίχο (wall) που (που) η (η) TMemoryStream.LoadFromFile χτυπά (hits), απλώς μετατοπισμένο (moved) από (από) (τη) (την) δεσμευμένη (committed) RAM (στ)στη (στη) (δ)δέσμευση (reservation) χώρου (χώρου) διευθύνσεων (διευθύνσεων). (Μια) (Μια) (Μια) Μια χαρτογράφηση πλήρους αρχείου (full-file mapping) δεν είναι (is no) (λ)λύση (fix) στο (στο) (σ)στο (στα) (σ)32-bit (32-bit), (α)απλώς (απλώς) η (η) (ίδια) ίδια (ίδια) (αποτυχία) αποτυχία (αποτυχία) πίσω από (behind) ονόματα API που (που) (ακούγονται) ακούγονται (ακούγονται) (καλύτερα) καλύτερα (καλύτερα) (καλύτερα) (καλύτερα) (καλύτερα)
Η (The) λύση (fix) (ε)είναι (είναι) (ο διαχωρισμός) (ο διαχωρισμός) (ο) ο διαχωρισμός (διαχωρισμός) των δύο (δύο) πραγμάτων που κάνει μια χαρτογράφηση. Η CreateFileMapping δημιουργεί το αντικείμενο τομέα (section object) και δεν κοστίζει καθόλου (at all) (χ)χώρο (χώρο) (διευθύνσεων) διευθύνσεων (διευθύνσεων), (α)ανεξάρτητα από (ανεξάρτητα από) (τ)το (τ)το (μέγεθος) μέγεθος (μέγεθος) (του) (του) (του αρχείου) αρχείου (αρχείου). Μόνο η (Μόνο η) MapViewOfFile καταναλώνει (spends) (χ)χώρο (χώρο) διευθύνσεων (διευθύνσεων), (κ)και τίποτα (και τίποτα) (τίποτα δεν) δεν (τίποτα δεν) την (την) αναγκάζει (αναγκάζει) να (να) (χαρτογραφήσει) χαρτογραφήσει (χαρτογραφήσει) ολόκληρο τον (ολόκληρο τον) τομέα: παίρνει (takes) ένα (ένα) 64-bit (64-bit) αρχικό (starting) (offset) offset (offset) και ένα (ένα) (μήκος) μήκος (μήκος) (προβολής) προβολής (προβολής). (Δ)Δημιουργήστε (Δημιουργήστε) (τον) (τον) (τον) τον τομέα μία φορά (μία φορά), χαρτογραφήστε (map) (μια) (μια) (μια) (μια προβολή) μια προβολή (προβολή) (64) 64 (64) έως (έως) 256 MB (256 MB) (πάνω από) πάνω από (πάνω από) (την) (την) περιοχή που (αναλύεται) αναλύεται (αναλύεται), (α)αποχαρτογραφήστε (αποχαρτογραφήστε) (π)πριν (πριν) ολισθήσετε παρακάτω (ολισθήσετε παρακάτω): το κόστος (κόστος) (στον) στον χώρο διευθύνσεων είναι ένα (ένα) (π)παράθυρο (παράθυρο), (ό)όχι (όχι) ένα (ένα) αρχείο (αρχείο). Μία (Μία) (πε) (ένα) (π)περιορισμός (constraint): τα offsets των προβολών (των προβολών) πρέπει να είναι (πρέπει να είναι) πολλαπλάσια (πολλαπλάσια) (τ)του (του) SYSTEM_INFO.dwAllocationGranularity, 64 KB (64 KB) στην πράξη (στην πράξη), οπότε (ένα αίτημα) (οπότε) ένα αίτημα (αίτημα) (για) για offset (offset) 1,000,000 στρογγυλοποιείται προς τα κάτω (rounded down) στα 983,040 (983,040) (κ)και ο δείκτης (δείκτης) (του) του (κλήτορα/caller) καλούντος (καλούντος) προσαρμόζεται προς τα εμπρός (adjusted forward) (κ)κατά τη διαφορά (κατά τη διαφορά)
(Ένας mapper) Ένας mapper (mapper) (μ)με ολισθαίνον παράθυρο στο Delphi
Η (The) παρακάτω κλάση (κλάση) (τ)τυλίγει (τυλίγει) (ο)ολόκληρη την (ολόκληρη την) πειθαρχία: (ένα αντικείμενο) (ένα αντικείμενο) (ένα αντικείμενο τομέα) ένα αντικείμενο τομέα, (μ)μια ζωντανή (live) προβολή, επαναστοίχιση κρυσταλλικότητας (granularity realignment), και (αναγνώσεις) (αναγνώσεις) αναγνώσεις που (αναγνώσεις που) (διασχίζουν) διασχίζουν (διασχίζουν) ένα όριο (όριο) (παραθύρου) παραθύρου (παραθύρου) που διαχειρίζονται μεγαλώνοντας (μεγαλώνοντας) αυτή τη (αυτή τη) (μία) μία προβολή (μία προβολή) αντί για (αντί για) το ράψιμο (ράψιμο) δύο (δύο)
uses
Winapi.Windows, System.SysUtils;
type
TWindowedFileMapper = class
private
FFile: THandle;
FMapping: THandle;
FFileSize: Int64;
FGranularity: DWORD; // SYSTEM_INFO.dwAllocationGranularity
FWindowSize: NativeUInt; // default view size
FViewBase: PByte; // base of the current view (aligned)
FViewOffset: Int64; // file offset FViewBase corresponds to
FViewSize: NativeUInt; // bytes mapped in the current view
procedure Unmap;
public
constructor Create(const FileName: string;
WindowSize: NativeUInt = 64 * 1024 * 1024);
destructor Destroy; override;
function Map(Offset: Int64; Size: NativeUInt): PByte;
procedure ReadBytes(Offset: Int64; var Buffer; Count: NativeUInt);
property FileSize: Int64 read FFileSize;
end;
constructor TWindowedFileMapper.Create(const FileName: string;
WindowSize: NativeUInt);
var
Info: TSystemInfo;
begin
inherited Create;
FFile := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if FFile = INVALID_HANDLE_VALUE then
RaiseLastOSError;
if not GetFileSizeEx(FFile, FFileSize) then
RaiseLastOSError;
// The section object reserves no address space, whatever the file size
FMapping := CreateFileMapping(FFile, nil, PAGE_READONLY, 0, 0, nil);
if FMapping = 0 then
RaiseLastOSError;
GetSystemInfo(Info);
FGranularity := Info.dwAllocationGranularity; // 64 KB in practice
FWindowSize := WindowSize;
end;
destructor TWindowedFileMapper.Destroy;
begin
Unmap;
if FMapping <> 0 then CloseHandle(FMapping);
if FFile <> INVALID_HANDLE_VALUE then CloseHandle(FFile);
inherited;
end;
procedure TWindowedFileMapper.Unmap;
begin
if FViewBase <> nil then
begin
UnmapViewOfFile(FViewBase);
FViewBase := nil;
FViewSize := 0;
end;
end;
function TWindowedFileMapper.Map(Offset: Int64; Size: NativeUInt): PByte;
var
AlignedOffset: Int64;
Delta, MapSize: NativeUInt;
begin
if (Offset < 0) or (Offset + Int64(Size) > FFileSize) then
raise ERangeError.CreateFmt(
'Map request at %d for %d bytes is outside the file',
[Offset, Int64(Size)]);
// Fast path: the requested range already sits inside the live view
if (FViewBase <> nil) and (Offset >= FViewOffset) and
(Offset + Int64(Size) <= FViewOffset + Int64(FViewSize)) then
Exit(FViewBase + NativeInt(Offset - FViewOffset));
Unmap; // slide: never hold two views at once
// Views must start on an allocation-granularity boundary
AlignedOffset := Offset - (Offset mod FGranularity);
Delta := NativeUInt(Offset - AlignedOffset);
MapSize := FWindowSize;
if MapSize < Size + Delta then // request straddles the window end:
MapSize := Size + Delta; // grow this one view to cover it
if AlignedOffset + Int64(MapSize) > FFileSize then
MapSize := NativeUInt(FFileSize - AlignedOffset); // clamp at EOF
FViewBase := MapViewOfFile(FMapping, FILE_MAP_READ,
DWORD(AlignedOffset shr 32), DWORD(AlignedOffset and $FFFFFFFF),
MapSize);
if FViewBase = nil then
RaiseLastOSError;
FViewOffset := AlignedOffset;
FViewSize := MapSize;
Result := FViewBase + NativeInt(Delta);
end;
procedure TWindowedFileMapper.ReadBytes(Offset: Int64; var Buffer;
Count: NativeUInt);
begin
Move(Map(Offset, Count)^, Buffer, Count);
end;
(Δύο λεπτομέρειες) Δύο λεπτομέρειες (σηκώνουν το βάρος) σηκώνουν το βάρος (σηκώνουν το βάρος). Η γρήγορη διαδρομή (fast path) (στην κορυφή) στην κορυφή (της) (του) της Map (της) επιστρέφει έναν (έναν) (έναν δείκτη) δείκτη χωρίς (χωρίς) καμία μετάβαση πυρήνα (καμία μετάβαση πυρήνα) (ό)όταν (όταν) (όταν) (το) (η) (η) το αιτούμενο εύρος (αιτούμενο εύρος) ήδη (ήδη) (κάθεται) κάθεται (κάθεται) (μέσα) μέσα (μέσα) στη ζωντανή προβολή· χάρη (χάρη) στη (στη) συσταδοποίηση των object-stream (object-stream clustering) (αυτή είναι) αυτή είναι η (η) (συνήθης) συνήθης περίπτωση (περίπτωση) (κ)και (και από) (και) από εκεί προέρχεται η (από) (ε)εκεί προέρχεται (εκεί προέρχεται) η εξοικονόμηση (εξοικονόμηση). Και ένα αίτημα (αίτημα) που (που) διασχίζει (διασχίζει) (τ)το τέλος του (το τέλος του) (προεπιλεγμένου) προεπιλεγμένου παραθύρου (παραθύρου) μεγαλώνει (μεγαλώνει) (το) το (το) MapSize για (για) αυτή τη (αυτή τη) μία προβολή (μία προβολή) αντί να (αντί να) (ρ)ράβει (ράβει) (δύο) δύο (δύο), πράγμα που (πράγμα που) (κ)κρατά τη (κρατά τη) (τ)τη ReadBytes μία γραμμή (μία γραμμή) (κ)και τους καλούντες (και τους καλούντες) (κ)και απαλλαγμένους (απαλλαγμένους) από βρόχους μερικής ανάγνωσης (από βρόχους μερικής ανάγνωσης)
Το μέγεθος του παραθύρου (παραθύρου) είναι ένα (ένα) ελαστικό κουμπί (forgiving knob): στα 64 MB (64 MB) μια (μια) (μια πλήρης σάρωση) πλήρης σάρωση ενός αρχείου 1.8 GB είναι 29 προβολές, στα (στα) (στα) 256 MB είναι 8 (8) (αλλά) αλλά (αλλά) κάθε δέσμευση είναι (κάθε δέσμευση είναι) πιο δύσκολο (πιο δύσκολο) να (να) (τοποθετηθεί) τοποθετηθεί σε έναν (σε έναν) (σε έναν) κατακερματισμένο (κατακερματισμένο) χώρο 32-bit (32-bit space), και κάτω από (κάτω από) (π)περίπου (περίπου) (τα) τα 16 MB τα αρχεία (τα αρχεία) (π)που (που) έχουν βαριά (βαριά) (ά)άλματα (άλματα/hops) αναχαρτογραφούνται (αναχαρτογραφούνται) (α)αρκετά συχνά (αρκετά συχνά) (ώστε) ώστε (ώστε) να γίνεται αισθητό (να γίνεται αισθητό). Οπουδήποτε στο εύρος (στο εύρος) 64 έως (έως) 256 MB, η κίνηση του map (map traffic) είναι στατιστικός θόρυβος (στατιστικός θόρυβος)
Μετρώντας τα (τα) syscalls
Τώρα η (η) (αριθμητική) αριθμητική. Αρχείο (Αρχείο) (δ)δοκιμής: 1.8 GB, 300,000 έμμεσα (έμμεσα) αντικείμενα (αντικείμενα) με μέσο όρο (με μέσο όρο) (π)περίπου (περίπου) 600 bytes ωφέλιμου φορτίου (ωφέλιμου φορτίου). Ένας (Ένας) αναλυτής (αναλυτής) (αναλυτής/parser) (α)ανά αντικείμενο (ανά αντικείμενο) αντλεί (αντλεί/fetches) το (το) καθένα με SetFilePointerEx συν μια ReadFile 4 KB: 600,000 μεταβάσεις πυρήνα (μεταβάσεις πυρήνα). Μια κλήση συστήματος (κλήση συστήματος/syscall) για (για) κρυφά αποθηκευμένη (κρυφά αποθηκευμένη/cached) (α)ανάγνωση (ανάγνωση) (κ)κάνει κύκλο (κάνει κύκλο/round-trips) (σ)σε (σε) περίπου 1.5 μs στο (στο) (τρ)τρέχον (τρέχον) (υ)υλικό (υλικό) x64, οπότε αυτό (αυτό) είναι (είναι) 600,000 × 1.5 μs ≈ 0.9 δευτερόλεπτα (δευτερόλεπτα) (κ)καθαρού (καθαρού) (κ)κόστους πυρήνα (κόστους πυρήνα/kernel overhead) πριν (πριν) την (την) (α)ανάλυση (ανάλυση) (ε)ενός (ενός) μοναδικού (μοναδικού) (byte) byte — η καλύτερη (καλύτερη) περίπτωση (περίπτωση) ζεστής μνήμης (ζεστής μνήμης/warm-cache). Κρύο (Κρύο), κάθε άλμα (άλμα) (ε)είναι (είναι) μια λειτουργία (μια λειτουργία) (σ)συσκευής: (στ)στην (στην) αποτελεσματική λανθάνουσα (αποτελεσματική λανθάνουσα/effective latency) κατάσταση των ~20 μs των (των) τυχαίων αναγνώσεων 4 KB από (από) (N)NVMe (NVMe), 300,000 από (από) (α)αυτές (αυτές) κοστίζουν (κοστίζουν) περίπου (περίπου) 6 δευτερόλεπτα χρόνου συσκευής (χρόνου συσκευής/device time)· (σ)σε (σε) αποθήκευση κατηγορίας (αποθήκευση κατηγορίας) SATA (SATA), λεπτά (λεπτά)
Οι αναγνώσεις (Οι αναγνώσεις) (κ)κινούν (κινούν) επίσης (επίσης) (τ)τα (τα) λάθος δεδομένα (λάθος δεδομένα): 300,000 × 4 KB ωθεί (ωθεί) 1.2 GB (μ)μέσα από (μέσα από) buffer χρήστη (buffer χρήστη) για να (για να) (π)παραδώσει (παραδώσει) περίπου (περίπου) 180 MB ωφέλιμου φορτίου (ωφέλιμου φορτίου) — (έξι) (έ)εξαπλάσια (εξαπλάσια) (ε)ενίσχυση (ενίσχυση), (κ)κάθε (κάθε) (byte) byte (α)αντιγράφεται (αντιγράφεται) (α)από (από) (τον) τον (π)πυρήνα (πυρήνα) (στ)στον (στον) χρήστη (χρήστη)
Ένα (Ένα) (Ένα) (b)buffer (buffer) προανάγνωσης (προανάγνωσης) με μέγεθος προσαρμοσμένο (με μέγεθος προσαρμοσμένο) στις συστάδες (στις συστάδες) object-stream είναι η πρώτη (είναι η πρώτη) ειλικρινής βελτίωση (ειλικρινής βελτίωση): μία ανάγνωση (μία ανάγνωση) 256 KB ανά (ανά) συστάδα αντί για (αντί για) (μ)μία ανά (μία ανά) αντικείμενο μειώνει τον (μειώνει τον) (α)αριθμό των μεταβάσεων κατά μία (αριθμό των μεταβάσεων κατά μία) (έ)έως δύο τάξεις (έως δύο τάξεις) (μ)μεγέθους (μεγέθους). Είναι (Είναι) (επ)επίσης (επίσης) το σωστό εργαλείο (το σωστό εργαλείο) όταν (όταν) (η) η χαρτογράφηση είναι άβολη (η χαρτογράφηση είναι άβολη/awkward), (συν)συνήθως (συνήθως) (στ)στις (στις) πλειοψηφίες των (πλειοψηφίες των) δικτυακών μεριδίων (δικτυακών μεριδίων/network shares)
Ο (Ο) χαρτογράφος (χαρτογράφος/mapper) (μ)με τα παράθυρα πηγαίνει πιο πέρα (με τα παράθυρα πηγαίνει πιο πέρα). (Μια) Μια πλήρης σάρωση (πλήρης σάρωση) είναι (είναι) 29 (29) κλήσεις (κλήσεις) (τ)της MapViewOfFile και (και) 29 της UnmapViewOfFile, (58) 58 (ρ)ρητές (ρητές/explicit) (με)μεταβάσεις (μεταβάσεις) έναντι (έναντι) 600,000. Μια πραγματική (Μια πραγματική) ανάλυση που καθοδηγείται από (ανάλυση που καθοδηγείται από) το (το) xref (xref) δεν είναι (δεν είναι) (μια) μια καθαρή (καθαρή) (σά)σάρωση (σάρωση), αλλά η γρήγορη (αλλά η γρήγορη) (δια)διαδρομή απορροφά κάθε (διαδρομή απορροφά κάθε) άντληση (άντληση) (μέσ)μέσα (μέσα) (στ)στο ζωντανό (στο ζωντανό) παράθυρο (παράθυρο)· ένα (ένα) πάσο δημιουργίας ευρετηρίου μεταδεδομένων (πάσο δημιουργίας ευρετηρίου μεταδεδομένων) (πά)πάνω από το (πάνω από το) αρχείο δοκιμής (αρχείο δοκιμής) (έκ)έκατσε (έκατσε/settled) σε μερικές (σε μερικές) (εκ)εκατοντάδες (εκατοντάδες) αναχαρτογραφήσεις (αναχαρτογραφήσεις/remaps). (Η) Η χαρτογράφηση δεν αφαιρεί (χαρτογράφηση δεν αφαιρεί) (ε)εργασία (εργασία) (απ)από τον (από τον) πυρήνα: μετατρέπει ρητές (μετατρέπει ρητές) κλήσεις συστήματος (κλήσεις συστήματος) (σ)σε (σε) σφάλματα (σφάλματα) (σε) σελίδας (σελίδας/page faults) που ο (που ο) διαχειριστής (διαχειριστής) (μν)μνήμης επιλύει σε (μνήμης επιλύει σε) συστάδες (συστάδες) πολλών σελίδων (πολλών σελίδων), απευθείας από την (απευθείας από την) κρυφή (κρυφή) (μν)μνήμη (μνήμη) του (του) αρχείου χωρίς αντίγραφο στον (αρχείου χωρίς αντίγραφο στον) χώρο (χώρο) του χρήστη, (κ)και οι περιοχές που (και οι περιοχές που) δεν (δεν) (αγγ)αγγίχτηκαν (αγγίχτηκαν) (πο)ποτέ δεν (ποτέ δεν) κοστίζουν τίποτα (κοστίζουν τίποτα). (Απ)Από (Από) την (την) (αρχ)αρχή μέχρι (αρχή μέχρι) το τέλος, το (το τέλος, το) πάσο (πάσο) δημιουργίας (δημιουργίας) ευρετηρίου πήγε από (ευρετηρίου πήγε από) (τ)τα (τα) 23 (23) (δευ)δευτερόλεπτα (δευτερόλεπτα) (κρ)κρύο (κρύο) (κ)και (και) 7.1 δευτερόλεπτα (7.1 δευτερόλεπτα) ζεστό με (ζεστό με) (αναγνώσεις ανά αντικείμενο στα) (αναγνώσεις) αναγνώσεις ανά αντικείμενο στα (ανά αντικείμενο στα) 6.5 (6.5) s κρύο (κρύο) (κ)και 1.9 (και 1.9) s ζεστό με τον mapper· αυτό που παραμένει είναι το zlib inflate, όχι (όχι) το IO
Πού ταιριάζει το FILE_FLAG_NO_BUFFERING
Το FILE_FLAG_NO_BUFFERING παρακάμπτει (bypasses) την (the) κρυφή (system cache) μνήμη συστήματος (system cache) με αντάλλαγμα (in exchange for) (σ)σκληρούς κανόνες (hard alignment rules) στοίχισης (στοίχισης): (τα) τα (offsets) offsets, (τα) τα μήκη (lengths), (κ)και (οι) οι διευθύνσεις των buffer (διευθύνσεις των buffer) πρέπει (all) να είναι όλα στοιχισμένα σε τομέα (sector-aligned). (Κερδίζει την αξία του) (Βγάζει τα λεφτά του) Κερδίζει την αξία του (Κερδίζει την αξία του) σε μεμονωμένες (single-pass) διαδοχικές (sequential) (εργασίες) εργασίες που διαφορετικά θα πλημμύριζαν (θα πλημμύριζαν) (τ)την κρυφή μνήμη (κρυφή μνήμη) (μ)με bytes (με bytes) (π)που (που) (κ)κανείς (κανείς) δεν διαβάζει δύο φορές — (μ)μια παρτίδα (παρτίδα) επανασειριοποίησης που ξαναγράφει ολόκληρο το αρχείο, (ή) ή (μ)ένα (μ)πάσο (πάσο) γραμμικοποίησης πάνω από την (πάνω από την) (ο)ολοκληρωμένη έξοδο (έξοδο). Με 4 (Με 4) έως (έως) 8 MB στοιχισμένων (στοιχισμένων) buffer πλησιάζει το (πλησιάζει το) διαδοχικό εύρος ζώνης της (διαδοχικό εύρος ζώνης της) συσκευής (συσκευής) (χωρίς) χωρίς να ρυπαίνει (χωρίς να ρυπαίνει) (τ)την κρυφή μνήμη
(Είναι εντελώς λάθος για ανάλυση) (Είναι εντελώς λάθος για ανάλυση). (Τυχαία άλματα) Τυχαία άλματα (xref) (μ)μέσω ενός (ενός) (μη προσωρινά αποθηκευμένου) (μη προσωρινά αποθηκευμένου/unbuffered) handle μετατρέπουν κάθε άντληση (μετατρέπουν κάθε άντληση) λεξικού 300-byte σε μια (λεξικού 300-byte σε μια) πλήρη (πλήρη) φυσική (φυσική) ανάγνωση (ανάγνωση) (χω)χωρίς (χωρίς) (κ)κρυφή (κρυφή) μνήμη για να (για να) απορροφήσει (απορροφήσει) (τ)τη δεύτερη (τη δεύτερη) (επί)επίσκεψη — (—) (κ)και η ανάλυση (και η ανάλυση) (PDF) PDF (ε)επανεπισκέπτεται (επανεπισκέπτεται) (συν)συνεχώς (συνεχώς) περιοχές (περιοχές), (ε)επειδή (επειδή) οι (οι) διαφορετικές (διαφορετικές) (σ)σελίδες (σελίδες) (αν)αναλύονται (αναλύονται) στα (στα) (ί)ίδια (ίδια) (αντι)αντικείμενα (αντικείμενα) (ρ)ροής (ροής). Unbuffered (Unbuffered) IO (IO) (γι)για (για) (τ)τη (τη) διαδοχική επανεγγραφή (διαδοχική επανεγγραφή), mapped (mapped) ή cached IO για (για) την τυχαία (την τυχαία) ανάλυση (ανάλυση)· η (η) (ση)σημαία (σημαία) είναι ανά handle (είναι ανά handle), (ε)επομένως μια (μια) (γρ)γραμμή (γραμμή/pipeline) μπορεί να (μπορεί να) (κρατήσει και τα δύο) (κρατήσει και τα δύο) στο (στο) (ίδ)ίδιο (ίδιο) (αρ)αρχείο (αρχείο)
(64-bit) 64-bit, σετ εργασίας (σετ εργασίας/working sets), και η πλευρά της (και η πλευρά της) (εγ)εγγραφής (εγγραφής/write side)
(Σε μια έκδοση 64-bit η αντίρρηση του) (Σε μια έκδοση 64-bit η αντίρρηση του) (Σε μια έκδοση 64-bit) (Σε μια έκδοση 64-bit η αντίρρηση του χώρου διευθύνσεων) (Σε) (Σε) (Σε) Μια (Σε μια) έκδοση 64-bit (έκδοση 64-bit) (έκδοση 64-bit) η (η) αντίρρηση του χώρου διευθύνσεων (αντίρρηση του χώρου διευθύνσεων) εξαφανίζεται (εξαφανίζεται): (π)περάστε το (περάστε το) μέγεθος του αρχείου (μέγεθος του αρχείου) ως παράθυρο (ως παράθυρο) (κ)και η (και η) παραπάνω (παραπάνω) κλάση υποβαθμίζεται σε μια (κλάση υποβαθμίζεται σε μια) μόνο (μόνο) πλήρη (πλήρη) (χ)χαρτογράφηση (χαρτογράφηση). (Η) Η παγίδα (παγίδα) σε υπηρεσίες (σε υπηρεσίες) μεγάλης διάρκειας (μεγάλης διάρκειας/long-running services): οι (οι) σελίδες μόνο για ανάγνωση που (σελίδες μόνο για ανάγνωση που) υποστηρίζονται από (υποστηρίζονται από) (α)αρχείο (αρχείο) (δ)δεν χρεώνουν (δεν χρεώνουν) (καμία δέσμευση) (καμία δέσμευση/commit), (ε)επομένως οι μετρητές (επομένως οι μετρητές) (δ)δέσμευσης (δέσμευσης) παραμένουν ήρεμοι (παραμένουν ήρεμοι), (α)αλλά (αλλά) (κ)κάθε σελίδα που (κάθε σελίδα που) αγγίζεται (αγγίζεται) μπαίνει (μπαίνει) στο σύνολο εργασίας (στο σύνολο εργασίας/working set)· (αναλύστε το) αναλύστε (αναλύστε) το μεγαλύτερο (μεγαλύτερο) μέρος από 1.8 GB (1.8 GB) και το σύνολο (και το σύνολο) εργασίας (εργασίας) μεγαλώνει (μεγαλώνει) (γι)για (για) να (να) ταιριάξει, διώχνοντας (διώχνοντας/evicting) όλα (όλα) (τ)τα (τα) (υπ)υπόλοιπα. (Τα) Τα οριοθετημένα παράθυρα (οριοθετημένα παράθυρα) βάζουν ταβάνι (βάζουν ταβάνι/ceiling) (σ)σε (σε) αυτό (αυτό), (ο)οπότε (οπότε) το ολισθαίνον μοτίβο (ολισθαίνον μοτίβο) παραμένει η (παραμένει η) σωστή προεπιλογή (σωστή προεπιλογή) ακόμα (ακόμα) και (και) όταν (όταν) (ο) ο χώρος (χώρος) διευθύνσεων (διευθύνσεων) είναι ελεύθερος (είναι ελεύθερος)
Στην (Στην) (πλ)πλευρά της εγγραφής (πλευρά της εγγραφής), (το φθηνότερο IO είναι το IO που δεν εκδόθηκε ποτέ). (Το) (Το φθηνότερο IO είναι το IO που δεν εκδόθηκε ποτέ). (Το φθηνότερο IO είναι το IO που δεν εκδόθηκε ποτέ). (Το) Το φθηνότερο IO είναι το IO που (δεν) (εκδόθηκε) δεν εκδόθηκε ποτέ (δεν εκδόθηκε ποτέ). (Ο) Ο μηχανισμός (μηχανισμός) (α)αυξητικής ενημέρωσης (αυξητικής ενημέρωσης) του (του) (P)PDF (ISO 32000-1 §7.5.6) προσαρτά τα (προσαρτά τα) τροποποιημένα αντικείμενα (τροποποιημένα αντικείμενα) και μια (και μια) (ν)νέα (νέα) (εν)ενότητα διασταυρούμενων αναφορών μετά (ενότητα διασταυρούμενων αναφορών μετά) (τα) (τ)τα (τ)αρχικά (αρχικά) bytes (bytes), (τ)τα οποία δεν (τα οποία δεν) (κ)κινούνται ποτέ (κινούνται ποτέ). (Το) Το σφράγισμα μιας (σφράγισμα μιας) σελίδας στο (σελίδας στο) (α)αρχείο 1.8 GB προσαρτά δεκάδες (αρχείο 1.8 GB προσαρτά δεκάδες) (k)kilobytes (kilobytes)· (μ)μια (μια) (πλ)πλήρης (πλήρης) (επ)επανεγγραφή (επανεγγραφή) (μ)μετακινεί και (μετακινεί και) (τ)τα 1.8 GB (τα 1.8 GB), πέντε (πέντε) (τά)τάξεις (τάξεις) (μ)μεγέθους μακριά (μεγέθους μακριά), (κ)και η προσάρτηση είναι (και η προσάρτηση είναι) (κ)καθαρά (καθαρά) (δ)διαδοχική (διαδοχική) (έ)έξοδος στην (έξοδος στην) ουρά
(Πού ταιριάζουν οι βιβλιοθήκες της losLab) Πού ταιριάζουν οι βιβλιοθήκες της losLab (Πού ταιριάζουν οι βιβλιοθήκες της losLab)
Και οι (Και οι) (δ)δύο βιβλιοθήκες PDF της losLab (βιβλιοθήκες PDF της losLab) (α)αποστέλλουν αυτή την πειθαρχία (αποστέλλουν αυτή την πειθαρχία) ως API (ως API). Το (Το) HotPDF Direct File API (Διαβάζει τον αριθμό των) (δ)διαβάζει τον (διαβάζει τον) αριθμό των (αριθμό των) σελίδων και τη δομή (σελίδων και τη δομή) (μ)μέσω μιας λαβής αρχείου (μέσω μιας λαβής αρχείου) χωρίς να (χωρίς να) (χ)χτίζει το (χτίζει το) δέντρο αντικειμένων (δέντρο αντικειμένων), αντιγράφει (αντιγράφει) και αποκρυπτογραφεί σε επίπεδο (και αποκρυπτογραφεί σε επίπεδο) (α)αρχείου (αρχείου), (κ)και γράφει (και γράφει) τα deltas (τα deltas) (μ)μέσω του BeginIncrementalUpdate — (—) η στρατηγική μόνο (η στρατηγική μόνο) για προσάρτηση παραπάνω, (γ)πακεταρισμένη (πακεταρισμένη). Το (Το) PDFlibPas ακολουθεί (ακολουθεί) (τ)την ίδια διαδρομή με (την ίδια διαδρομή με) το (το) (σ)στρώμα Direct Access (στρώμα Direct Access): (έ)ένας (ένας) streaming reader (streaming reader) (π)που περπατά τον (που περπατά τον) (π)πίνακα (πίνακα) (δ)διασταυρούμενων αναφορών στη (διασταυρούμενων αναφορών στη) θέση του (θέση του/in place), (α)αντλεί (αντλεί/fetches) τα αντικείμενα τεμπέλικα (τα αντικείμενα τεμπέλικα/lazily), εξάγει εύρη (εξάγει εύρη) σελίδων (σελίδων) από (από) (α)αρχείο (αρχείο) (σ)σε (σε) (α)αρχείο (αρχείο), (κ)και διατηρεί τις (και διατηρεί τις) (ε)επεξεργασίες ως αυξητικές αναθεωρήσεις (επεξεργασίες ως αυξητικές αναθεωρήσεις). (Α)Αν (Αν) (γ)γράφετε (γράφετε) (τ)τον (τον) (δ)δικό (δικό) (σ)σας αναλυτή (σας αναλυτή), (η) η κλάση (κλάση) (τ)του (του) mapper (mapper) (ε)είναι (είναι) (δ)δική σας (δική σας) (γ)για να την πάρετε (για να την πάρετε)· (α)αν (αν) τρέχετε (τρέχετε) (μ)μια γραμμή εγγράφου (μια γραμμή εγγράφου/document pipeline), αφήστε (αφήστε) (τ)τη (τη) βιβλιοθήκη να (βιβλιοθήκη να) (κ)κρατήσει το (κρατήσει το) παράθυρο (παράθυρο) ειλικρινές (ειλικρινές)
Σημείωση (Σημείωση): (Η βελτιστοποιημένη) Ο (Η βελτιστοποιημένη) βελτιστοποιημένος χειρισμός (βελτιστοποιημένος χειρισμός) IO για έγγραφα κλίμακας (έγγραφα κλίμακας) g (g)igabyte είναι ενσωματωμένος απευθείας (igabyte είναι ενσωματωμένος απευθείας) στο (στο) HotPDF VCL Component για (για) Delphi και C++Builder