@Kit: Po jak velkých blocích je nejoptimálnější načítat data ze souboru? Dejmetomu, že mám texťák s emaily a id-éčkama uživatelů, na začátku je hlavička s rejstříkama cca 2KB. Je nějaký rozdíl v rychlosti či odezvě v tom jestli napoprvé načtu 2kB, 4kB nebo 8kB? Opakuji, že jde jen o první načtení hlavičky, z toho zjistím přesné umístění bloku, ve kterém hledat email po přihlášení; Takový blok by pak měl mít prakticky mezi 50-250 znaky. Takže i kdyby měl soubor 4MB, během přihlašování načtu jen hlavičku a pak ten hledaný blok.
Optimální by mělo být 8 KiB, protože to je obvyklá velikost bufferu.
To je totiž dobrá otázka :-(
Na úrovni blokové vrstvy a zřejmě i filesystému je dnes nejmenší optimální velikost přístupové transakce na x86 pravděpodoně 4 kB, což je obvyklá velikost stránky VM a obvyklá velikost sektoru na blokové vrstvě. A nejlíp ještě zarovnat na hranice 4 kB od začátku souboru. Filesystém sice alokuje ve větších "clusterech", ale ty IMO nemusí naráz číst a zapisovat. (Odhlédněme od faktu, že donedávna obvyklá velikost sektoru na disku bývala 512 B - ono to na věci možná mnoho neměnilo, vzhledem k tomu, jak funguje v UNIXu memory management v těsné spolupráci s blokovou vrstvou a souborovými systémy. A odhlédněme od existence "huge pages" na Linuxu a snad i jinde.)
A Kit má naopak pravdu v tom, že 8 kB/kiB je alokační jednotka
Apache HTTPd "buckets", konkrétně:
/* default bucket buffer size - 8KB minus room for memory allocator headers */
#define APR_BUCKET_BUFF_SIZE 8000
Což osobně čtu tak, že user-space alokátor Apache si přidělenou virtuální paměť (přidělena kernelem po 4 kB) parceluje pro potřeby file IO po 8kB (8192 B), ale payloadu Vaší PHP aplikace z toho dává jenom 8 kiB (8000 B).
Kromě toho je v Linuxu na blokové vrstvě nějaký pevný read-ahead, by default to bývalo 128 kB. A nějaký svůj vlastní adaptivní read-ahead má souborová vrstva - a dá se tuším i ladit explicitním syscallem na otevřený file descriptor, což ale spousta softu nedělá. A při dlouhém sekvenčním zápisu jsem pozoroval, že Linux láme ten stream na ATA transakce dlouhé taky řádově pár set kB - a pokud moje transakce (předávané mým softwarem z user space) nebyly zarovnané na určité hranice mocniny dvou v LBA adresaci disku, tak mi je "lámal vejpůl", aby na blokové vrstvě na té hranici končil a začínal... už je to pár let, dneska to může být jinak.
Při čtení jednoho bloku (Vaše "hlavička") podle mého vůbec nemá smysl se zabývat velikostí čtecí transakce. Obecně důležité je, minimalizovat počet těch transakcí. Jestli načtete jenom 2 kB, které opravdu potřebujete, nebo budete spekulovat na celý bucket, to je myslím dost jedno. Tady bych doporučil: zbytečně to nedrobte. Pokud jde o jednu transakci, tak si prostě řekněte "svému prostředí" o ta data která potřebujete, ale netřeba to zbytečně nafukovat, nepomůžete si. Ony už si to "vrstvy mezi vámi a diskem" vhodně přifouknou a zarovnají (případně zlomí vejpůl, pokud se někde netrefíte na zarovnání).
Podle mého má smysl optimalizovat především *zápis*. Pokud máte data hezky za sebou = taková optimalizace je možná, zapisujte v co největších blocích (zas tak aby Vám to nezačlo dělat problémy s dostupným objemem RAM). Usnadníte tím práci fyzickým diskům - ať už se bude jednat o flash (erase bloky velké pár set kB až jednotky MB) nebo o točivý disk (pro transakce větší než 1 MB se průchodnost v random zátěži začíná blížit průchodnosti sekvenční). Nemá ale smysl, dělat kvůli tomu po svém nějaký read-ahead a write-back, protože potřebujete zapsat 1 B a chcete to systému usnadnit. To je blbost - pokud potřebujete drobné zápisy rozprostřené po ploše, tak se asi nedá nic dělat, a uděláte líp, když to necháte na operačním systému.
Obecně třeba ten bucketový systém v Apačovi je podle mého původně myšlen tak, aby bylo možno transparentně optimalizovat práci s daty na souborovém systému / na disku. A dost jsem se svého času vztekal, že konkrétně pro problém "mnoho paralelních čtoucích sekvenčních klientů nad točivým diskem" ty buckety rozhodně nejsou optimalizované a není je jak ladit. (Jednotná velikost bucketu, nulová možnost práce s maličkými transakcemi vs. s read-aheadem pro zjevně sekvenční streamy. Leda by člověk celou tu bucketovou vrstvu zásadně přepsal.) Asi to docela dobře sedí na VM vrstvu s její 4kB velikostí stránky.