
Tlhaloso
Ho na le ts'ebeliso e bonolo le e bohlokoa haholo lefatšeng - , 'me ho ile ha etsahala hore e be e metse ka metso mosebetsing oa rona oa tlhahiso ka nako e telele haholo (le hoja ho ne ho sa khonehe ho kenya phetolelo ea eona, empa ka sebele e ne e se eona ea ho qetela e fumanehang). Re e sebelisa bakeng sa morero oa eona - ho haha li-patches tsa binary. Haeba u sheba se ka polokelong, e ba masoabi hanyane: ha e le hantle, e lahliloe khale haholo 'me boholo ba eona e siiloe ke nako (mosebetsi-'moho le 'na o kile a etsa liphetoho tse' maloa moo, empa e ne e le khale) . Ka kakaretso, ke ile ka etsa qeto ea ho tsosa taba ena: Ke ile ka ferekana, ka lahla seo ke neng ke sa rera ho se sebelisa, ka fetisetsa morero ho. , li-microfunctions tse "chesang" tse kentsoeng ka har'a "chesang", li tlositse lihlopha tse kholo ho tloha ho stack (le mefuta e mengata ea bolelele bo fapaneng, e etsang hore ke be "bomo"), e ile ea boela ea matha profil - mme ea fumana hore hoo e ka bang 40% ea nako e sebelisitsoe ho. ...
Joale ho thoe'ng ka fwrite?
Khoutung ena, fwrite (boemong ba ka bo ikhethileng ba tlhahlobo: ho aha patch lipakeng tsa lifaele tse haufi tsa 300 MB, data ea ho kenya e mohopolong ka botlalo) e bitsoa makhetlo a limilione ka boholo bo nyane ba buffer. Ho totobetse hore ntho ena e tla fokotseha, ka hona ke rata ho susumetsa ka tsela e itseng ho hlajoa ke lihlong. Ha ho na takatso leha e le efe ea ho kenya ts'ebetsong mefuta e fapaneng ea mehloli ea data, asynchronous input-output, ke ne ke batla ho fumana tharollo e bonolo. Ntho ea pele e ileng ea tla kelellong ke ho eketsa boholo ba buffer
setvbuf(file, nullptr, _IOFBF, 64* 1024)empa ha kea ka ka fumana ntlafatso e kholo sephethong (hona joale fwrite e nka hoo e ka bang 37% ea nako) - e bolelang hore e ntse e se taba ea ho ngola khafetsa data ho disk. Ha u sheba "tlas'a hood" ea fwrite, u ka bona hore senotlolo / notlolla sebopeho sa FILE se etsahala ka hare ho ntho e kang ena (pseudo-code, tlhahlobo eohle e entsoe tlas'a Visual Studio 2017):
size_t fwrite (const void *buffer, size_t size, size_t count, FILE *stream)
{
size_t retval = 0;
_lock_str(stream); /* lock stream */
__try
{
retval = _fwrite_nolock(buffer, size, count, stream);
}
__finally
{
_unlock_str(stream); /* unlock stream */
}
return retval;
}
Ho ea ka profil, _fwrite_nolock e nka 6% feela ea nako, tse ling kaofela li holimo. Boemong ba ka, polokeho ea likhoele e hlakile haholo, ka hona ke tla e tela ka ho nkela mohala oa fwrite sebaka ka - ha ho hlokahale hore u be bohlale ka likhang. Kakaretso: bolotsana bona bo bonolo bo fokolitse haholo litšenyehelo tsa ho rekota sephetho, seo phetolelong ea pele e neng e lekana le halofo ea nako e sebelisitsoeng. Ka tsela, lefats'eng la POSIX ho na le ts'ebetso e ts'oanang - . Ka kakaretso, ho tšoana le ho fread. Ka hona, ka ho sebelisa para ea #defines, u ka fumana tharollo ea sefapano ka ho feletseng ntle le liloko tse sa hlokahaleng haeba li sa hlokahale ('me sena se etsahala hangata).
fwrite, _fwrite_nolock, setvbuf
A re tloheng morerong oa pele 'me re tsepamise maikutlo ho lekeng nyeoe e itseng: ho ngola faele e kholo (512 MB) ka likotoana tse nyane haholo—byte e le 'ngoe ka' ngoe. Sistimi ea teko: AMD Ryzen 7 1700, 16 GB RAM, 7200 rpm HDD, cache ea 64 MB. Windows 10 Ka 1809, binary e hahiloe e le 32-bit, ntlafatso e a nolofalloa, laeborari e hokahantsoe ka mokhoa o sa fetoheng.
Mohlala oa teko:
#include <chrono>
#include <cstdio>
#include <inttypes.h>
#include <memory>
#ifdef _MSC_VER
#define fwrite_unlocked _fwrite_nolock
#endif
using namespace std::chrono;
int main()
{
std::unique_ptr<FILE, int(*)(FILE*)> file(fopen("test.bin", "wb"), fclose);
if (!file)
return 1;
constexpr size_t TEST_BUFFER_SIZE = 256 * 1024;
if (setvbuf(file.get(), nullptr, _IOFBF, TEST_BUFFER_SIZE) != 0)
return 2;
auto start = steady_clock::now();
const uint8_t b = 77;
constexpr size_t TEST_FILE_SIZE = 512 * 1024 * 1024;
for (size_t i = 0; i < TEST_FILE_SIZE; ++i)
fwrite_unlocked(&b, 1, sizeof(b), file.get());
auto end = steady_clock::now();
auto interval = duration_cast<microseconds>(end - start);
printf("Time: %lldn", interval.count());
return 0;
}
Liphetoho e tla ba TEST_BUFFER_SIZE, 'me maemong a' maloa re tla nkela fwrite_unlocked sebaka ka fwrite. Ha re qaleng ka nyeoe ea fwrite ntle le ho beha boholo ba buffer ka ho hlaka (tlhalosetsa setvbuf le khoutu e amanang): nako 27048906 µs, lebelo la ho ngola - 18.93 MB/s. Joale ha re behe boholo ba buffer ho 64 KB: nako - 25037111 μs, lebelo - 20.44 Mb/s. Joale ha re lekeng ts'ebetso ea _fwrite_nolock ntle le ho letsetsa setvbuf: 7262221 µs, lebelo - 70.5 Mb/s!
Ka mor'a moo, a re lekeng ka boholo ba buffer (setvbuf):

Lintlha li ile tsa fumanoa ka kakaretso ea liteko tse 5; Ke ne ke le botsoa haholo ho bala liphoso. Ha e le 'na, 93 MB/s ha u ngola 1 byte ho HDD e tloaelehileng ke sephetho se setle haholo, u hloka feela ho khetha boholo bo nepahetseng ba buffer (boemong ba ka, 256 KB e nepahetse) ebe u kenya sebaka sa fwrite ka _fwrite_nolock/fwrite_unlocked ( haeba ts'ireletso ea khoele e sa hlokehe, ehlile).
Ka mokhoa o ts'oanang le fread maemong a tšoanang. Kaha ha ke na mochine oa hardware o nang le Linux haufi (lik'homphieutha tse nang le boto e le 'ngoe ha li bale), ke ile ka etsa qeto ea ho etsa liteko tse fokolang mochine oa sebele (Hyper-V, OpenSUSE 15, GCC 8.3.1) - the paterone, ha e le hantle, e tšoana: "feela" fwrite 20 Mb/s, fwrite + 256 KB buffer e hlahisitse 23 Mb/s, fwrite_unlocked ka buffer e tšoanang - 35 Mb/s (64-bit binary, assembled g++ -o2 - s -static-libgcc -static-libstdc++ fwrite_test. cpp -o fwrite_test).
Afterword
Sepheo sa ho ngola sehlooho sena e ne e le ho hlalosa mokhoa o bonolo le o sebetsang maemong a mangata (ha ke e-s'o kopane le _fwrite_nolock / fwrite_unlocked mesebetsi pele, ha e ratoe haholo - empa ke lefeela). Ha ke etse eka boitsebiso boo ke bo bocha, empa ke tšepa hore sehlooho seo se tla ba molemo ho sechaba.
Source: www.habr.com
