[c++] ускорение чтения блочной информации

Maurog

имеется файл размеры порядка 2 Г
там лежат пакеты - блоки инфы с хедером в 4 байта (в них тип инфы и размер следующего блока)
так вот очень часто по хедеру ясно, что тело пакета по сути не нужно и хочется его быстро пропустить.
однако оказалось, что .seekg(f,PacketLength,ios::cur) жрет больше времени, чем .read(tmpbuffer, PacketLength).
то есть по сути быстрее все же перелопатить файл, чем грамотно его обпрыгать
как такое могло выйти?
должно ли так быть?
файл открывается типа
 

filebuf fb;
fb.open(filename,ios::read)
istream In(&fb);
In.read...In.seekg;

все под линуксом, соляркой и на НФС
есть ли другие методы быстро обпрыгать файл?

margadon

а как-нить его замэпить в память?

mira-bella

блин
и ежу ж понятно, что надо считывать крупные блоки из файла в оперативку, а потом их перелопачивать в оперативке любым подходящим способом. Т.е. не по 4 байта считывать, а хотя бы килобайт по 10 (а то и по несколько мегабайт) - это как минимум экономит огромное количество вызовов функций (команда call и кроме того такой подход не полагается на качество кеширования (потому что ты сам кешируешь). Конечно этот подход не везде уместен, но в данном случае вроде очень даже.

Maurog

то есть кроме считывания всего файла идей нету?
в данном случае, пожалуй, стрим вполне нормально кеширует.
прыгалок других нет?

kruzer25

А ведь тут была огромная тема по этому поводу... где-то в начале 2005...

mira-bella

то есть кроме считывания всего файла идей нету?
это где же ты заметил предложение считывать весь файл?

ppplva

Каков типичный размер блока ? Без это разговор вообще ни о чем.

mira-bella

в данном случае, пожалуй, стрим вполне нормально кеширует.
прыгалок других нет?
даже если stream (или ОС) достаточно хорошо кеширует, все равно прямой доступ к буферу многократно повысит скорость работы за счет гораздо меньшего количества call-ов (а call выполняется очень долго, в отличие от большинства других команд x86 процессора).

ppplva

Если средний блок - 100 байт, и
очень часто по хедеру ясно, что тело пакета по сути не нужно
то никуда не денешься, придется считывать все.

mira-bella

Если средний блок - 100 байт, и
очень часто по хедеру ясно, что тело пакета по сути не нужно
то никуда не денешься, придется считывать все.
во-первых: во избежание недоразумений "придется считывать все" это уж конечно не весь файл за раз.
во-вторых: считать промежуточные ненужные блоки в составе считываемого за один вызов большого блока вообще не затратно - они и так уже считаны в кеш, а скопировать блок памяти из кеша в наш буфер один раз обычно намного выгоднее чем вызвать много раз функции (даже если эти функции почти ничего не делают). Поэтому считать все в буфер, а потом его интерпретировать почти без вызовов функций - намного выгоднее чем вызывать много раз функцию считывания мелких блоков (хедеров и нужных блоков) и функцию пропуска ненужных блоков.
НО если с точки зрения стиля программа, пользующаяся кучей вызовов, выглядит красиво, логично и понятно, то не надо портить ее оптимизациями, а надо оставить как есть ИМХО.

ppplva

"придется считывать все" - это в конечном итоге
Поэтому лучше, конечно, читать большими кусками или вообще замапить на память.

rosali

а call выполняется очень долго, в отличие от большинства других команд x86 процессора
Просто нет слов Наверное ты 10 (15?) лет назад прочитал КНИГУ, в которой около каждой инструкции было написано время выполнения в тактах, да? Так вот сообщаю тебе - эта КНИГА потеряла актуальность...

Ivan8209

Думаешь, это заранее закешируется?
---
...Я работаю антинаучным аферистом...

rosali

Ну просто нет смысла фантазировать насчет времени работы какого то кода на основании информации десятилетней давности. Да скорее всего и в современном процессоре call в 20 раз медленнее чем mov на регистрах. Ну и что, любая программа в основном время теряет совсем не там. Любой syscall, даже тривиальный - это тысячи, даже десятки тысяч тактов. Доступ к памяти, которая не в кеше - до сотни тактов. Я уж молчу о том, что вызов функции в С имеет довольно косвенное отношение к инструкции call.
Буферизация в fstream-е разумеется есть, зачем еще свою городить? Хотя возможно я избалован достойными реализациями STL в VS, может в gcc все и по другому?..

Ivan8209

Вроде бы человеку нужен aio.
---
...Я работаю антинаучным аферистом...

Maurog

окей
идею понял
то есть достаточно сделать надстройку над istream с таким же интерефейсом (методы .seekg .read но фактически при вызове .read(dst,iLength) он сделает

memcpy(dst,Buffer+iCurrentPointer,iLength);
iCurrentPointer+=iLength;

а буфер - это char [30Mbite].
когда iCurrentPointer подлезет к концу внутреннего буфера-сделать подкачку объемом 30Мбайт.
тем самым мы избежим много мелких чтений из файла
правильно я понял?

Ivan8209

man setbuf
---
...Я работаю антинаучным аферистом...

alexkravchuk

ты лучше скажи, какого размера у тебя блоки - яснее будет. Если меньше 1000 байт, но ничего умного не придумаешь в любой случае.
А ещё учти, что пропускная способность сети (у тебя ведь NFS) и жёсткого диска сильно ограничены по сравнению с оперативной памятью, и поэтому вся та оптимизация, о которой ты говоришь - фактически бессмысленна. Системные вызовы оптимизировать - нужно, а остальное - врят ли.

mira-bella

Просто нет слов Наверное ты 10 (15?) лет назад прочитал КНИГУ, в которой около каждой инструкции было написано время выполнения в тактах, да? Так вот сообщаю тебе - эта КНИГА потеряла актуальность...
нифига не угадал
кроме книг и интернета у меня еще есть мозг - очень полезный девайс говорят
и вот если им воспользоваться, то и ежу понятно даже без специальных знаний, что jmp/jX, тем более call (и еще более int) должны выполнятся значительно дольше большинства команд на современных процах уже только потому, что получается гораздо менее эффективное кеширование кода и ковейерная оптимизация (хотя в проце конечно могут при этом присутствовать всякие навороты, предсказывающие переходы, и т.п.). Не говоря уже о том, что для call-а (и ret-а) требется доступ к стеку (т.е. к оперативке а доступ к оперативке сам по себе является узким местом.
PS как раз 15 лет назад это было не особо актуально вследствие отсутствия или убогости кеширования и конвейеров.

Ivan8209

> и ежу понятно даже без специальных знаний, что jmp/jX, тем более call
> (и еще более int) должны выполнятся значительно дольше большинства команд на современных процах
Наглая ложь.
> Не говоря уже о том, что для call-а (и ret-а) требется доступ к стеку
Ещё более наглая ложь.
---
...Я работаю антинаучным аферистом...

kruzer25

> Не говоря уже о том, что для call-а (и ret-а) требется доступ к стеку
Ещё более наглая ложь.
О, я уже узнаю КОНТРУ, не смотря на ник...
Поясни.

Ivan8209

В наиболее продвинутых процессорах существует команда "branch and link to register."
В менее продвинутых процессорах указатель возврата после прерывания запоминается в регистр.
---
"Narrowness of experience leads to narrowness of imagination."

mira-bella

Ну просто нет смысла фантазировать насчет времени работы какого то кода на основании информации десятилетней давности.
просто нет смысла фантазировать насчет использования кем-то литературы/представлений десятилетней давности.
Да скорее всего и в современном процессоре call в 20 раз медленнее чем mov на регистрах.
вероятно много больше 20, потому что "Доступ к памяти, которая не в кеше - до сотни тактов." (це, епт)
Надеюсь не надо объяснять где аж дважды последовательно происходит доступ к памяти во время выполнения каждой из команд call и ret? (причем один из этих двух доступов вероятно не в кеше)
Ну и что, любая программа в основном время теряет совсем не там.
как раз именно там:
Любой syscall, даже тривиальный - это тысячи, даже десятки тысяч тактов. Доступ к памяти, которая не в кеше - до сотни тактов.
Я говорю именно об этом же. Именно поэтому я и предлагаю минимизировать количество вызовов потенциальных syscall-ов и почти гарантированных call+ret, подразумевающих 2 последовательных доступа к опеативке в одной команде, и уж точно гарантированного блока лишних команд (в которых есть условные переходы, надеюсь не требуется уточнять - где именно).
Я уж молчу о том, что вызов функции в С имеет довольно косвенное отношение к инструкции call.
во-первых мы говорим о C++, хотя и его это утверждение касается.
во-вторых хоть и косвенное, но очень и очень даже имеет.
Буферизация в fstream-е разумеется есть, зачем еще свою городить?
я что не по-русски написал зачем?
Чтобы иметь непосредственный доступ в буфер и избавиться тем самым от многих вызовов функций, которые даже если инлайнятся, все равно жутко тормозят (хотя бы за счет условных переходов внутри них).
Хотя возможно я избалован достойными реализациями STL в VS, может в gcc все и по другому?..
fstream не относится к STL (но относится к стандартной библиотеке конечно)
Никак нельзя было обойтись без очередного пустого наезда на gcc в дискуссии не относящейся к этой теме вообще?
Еще скажи, что в VS все stream функции инлайнятся.
Но даже если так, в чем я очень сомневаюсь, все равно это весьма существенная оптимизация.

kamputer

>или вообще замапить на память.
Там, где заведомо нужен только последовательный доступ, мапинги не рулят.
Тем более, если доступ к файлу идёт по сети, лучше стараться максимально точно и явно контролировать, что и когда читается, чтоб минимизировать количество обращений.

Ivan8209

> просто нет смысла фантазировать
Заканчивать надо на этом месте.
Нет смысла рассуждать в отрыве от компилятора и операционной системы.
---
"Истина всегда конкретна."

mira-bella

В наиболее продвинутых процессорах существует команда "branch and link to register."
В менее продвинутых процессорах указатель возврата после прерывания запоминается в регистр.
Ты что головой ударился?
Или я название команд написал с ошибками?
Думаю все кроме тебя догадались, что речь идет о командах call/ret процессоров x86 - о них и только о них я и писал, когда употреблял слова "call" и "ret".
Написанные тобой команды конечно существуют на более продвинутых процесорах чем линейка x86, но и называются они почти всегда по другому (а не call и ret).

kamputer

>однако оказалось, что .seekg(f,PacketLength,ios::cur) жрет больше времени, чем .read(tmpbuffer, PacketLength).
Ну так полезай в исходники библиотеки, и посмотри, почему так получается. Интересно же.
И ещё я бы первым делом попробовал написать то же без использования STL / stdio.

mira-bella

Заканчивать надо на этом месте.
Нет смысла рассуждать в отрыве от компилятора и операционной системы.
То что я описывал повысит производительность независимо от компилятора и операционной системы, но степень этого повышения зависит от системы команд и архитектуры процессора и качества реализации stream и оптимизации компилятором. Я подразумевал использование относительно новых x86 процессоров, которыми почти все и пользуются, но и других процессоров это тоже касается - быть может в меньшей степени.

Ivan8209

А почему ты не подозревал о наличии разных систем на тех же процессорах?
---
...Я работаю антинаучным аферистом...

mira-bella

А почему ты не подозревал о наличии разных систем на тех же процессорах?
Каких "разных систем"? Операционных систем или систем команд?
И то и другое я подразумевал, о чем прямо сказал в предыдущем посте.

Ivan8209

Архитектур.
Один чёрт, от библиотеки и операционной системы сильно зависит.
Если есть средства для предварительного чтения, то можно что-то выжать,
если нет --- надо переходить на ОС, где есть.
---
"Истина грядёт --- её ничто не остановит!"

mira-bella

так вот очень часто по хедеру ясно, что тело пакета по сути не нужно и хочется его быстро пропустить.
однако оказалось, что .seekg(f,PacketLength,ios::cur) жрет больше времени, чем .read(tmpbuffer, PacketLength).
кстати, если считывание информации последовательное (т.е. без возвратов назад то использование seekg неуместно - надо использовать skip.

mira-bella

Один чёрт, от библиотеки и операционной системы сильно зависит.
согласен конечно
я об этом тоже писал
Но зависит не то будет или нет выигрыш - он будет почти всегда (особенно если буферизацию fstream отменить а то какой будет выигрыш и стоит ли ради него парится.
В любом случае, если заморочки с собственной буферизацией, эффективной для данной задачи, геморнее использования стандартной библиотеки, или ухудшают читабельность и логичность кода, или этот участок кода не является очень критичным для общей производительности, то не стоит парится.

Ivan8209

> а то какой будет выигрыш и стоит ли ради него парится.
Это совершенно другой вопрос.
Вообще-то странно, что никто не сказал про виндовые средства наподобие aio.
---
...Я работаю антинаучным аферистом...

ppplva

Там, где заведомо нужен только последовательный доступ, мапинги не рулят.
Насколько я знаю, копирование файлов через read/write и через mmap дает практически одинаковую скорость.

Marinavo_0507

> Там, где заведомо нужен только последовательный доступ, мапинги не рулят.
Спорный вопрос, на линуксе по крайней мере mmap и read рулят с переменным успехом.
Правда, сам тесты не запускал, читал lkml только.

bleyman

Надеюсь не надо объяснять где аж дважды последовательно происходит доступ к памяти во время выполнения каждой из команд call и ret? (причем один из этих двух доступов вероятно не в кеше)
Наглая ложь(с).
Во-первых, в рассматриваемом случае в кэше окажется вообще всё - и стек, и код вызывающей функции, и код вызываемой, и локальные переменные обеих. И call будет исполняться за один такт. Причём безусловный call даже не будет скидывать конвеер.
Во-вторых, задержки по доступу к винту превышают возможные задержки на вызовах функций эдак на шесть десятичных порядков. В миллион раз, то есть. Миллисекунды против наносекунд. И есть некоторая надежда, что выставление правильного размера буфера непосредственно у файла позволит оси оптимизировать именно эти, большие задержки. Например, будет более правильно использоваться внутренний буфер винта.

Maurog

эх
сделал тест:
без всяких обработок считал файл 1.7 Г блоками 200 байт - 2.5 минуты
затем блоками в 30Мб - 6 секунд.
сделал надстройку над истримом: чтобы через буфер 30Мб все делалось - ускорения никакого (в смысле полная читалка файла с обработкой значений- 4-5 минут все равно занимает)
ничего не понимаю=(
пакеты в файле имеют размеры от 4 байт до 200 в среднем
читается файл дважды последовательно

bleyman

>> затем блоками в 30Мб - 6 секунд.
280 мегабайт в секунду? Молодой человек, вы что-то не договариваете. Таких винтов небывает.

Maurog

эх...
оказывается все зависит от последовательности проверки.
если сначала по 200 читать, а потом по 30 Мб, то такой результат:

DBG: istream_read by 200 bites:162.556; 8607427 blocks readed
DBG: istream_read by 30Mbites bites:2.62639; 58 blocks readed

если же переставить, то такой:

DBG: istream_read by 30Mbites bites:152.937; 58 blocks readed
DBG: istream_read by 200 bites:2.57991; 8607427 blocks readed

вот так проверка делается:

char buf[30000001];
InStream.clear;
InStream.seekg(0);
h=GET_CURRENT_TIME;
int kk = 0;
do
{
istream_read(&InStream, buf, 30000000);
kk++;
}
while (InStream.rdstate == ios::goodbit );
cout <<"\nDBG: istream_read by 30Mbites bites:"<< GET_CURRENT_TIME-h << "; "<<kk<<" blocks readed";
cout.flush;
InStream.clear;
InStream.seekg(0);
h=GET_CURRENT_TIME;
kk = 0;
do {
kk++;
istream_read(&InStream, buf, 200);
}
while (InStream.rdstate == ios::goodbit );
cout <<"\nDBG: istream_read by 200 bites:"<< GET_CURRENT_TIME-h<< "; "<<kk<<" blocks readed";
cout.flush;

зы: мегабайт в этом топике равен 1 миллион байт
зы2: время выводится в секундах

Maurog

короче большими блоками если считывать, а не маленькими-тут выгрыш 6%, а если учитывать еще и обработку файла по ходу загрузки, то выгрыш нулевой =(
слишком долго считывается...
нужен маневр

Dasar

по задаче - ты файл обрабатываешь один раз, или много раз?

Maurog

это данные, которые надо показать (полигоны и тд).
читалка делает два прохода по файлу и создает внутреннюю структуру данных.
далее все в памяти происходит.

Dasar

вопрос на самом деле такой: может быть можно заранее один раз построить индексный файл? и дальше уже пользоваться им?

Maurog

я это называю кешированием.
этот метод отпадает.
нужно ли попробывать все на FILE* сделать?
есть ли вероятность, что fread даст лучшие результаты?

Maurog

я знаю, что есть софт, который открывает такие файлы в 20 раз быстрее..
осталось допетрить как
зы: хотя если они используют хорошую внутренную структуру данных, то им требуется одно прочтение файла...а это хороший выигрыш, но внутр структуру я не меняю и смирился с ней...
надо ускориться как-то ;(

Marinavo_0507

уважаемые, а вы заметили слово nfs в условии задачи?
маза это всё меняет

koly

Тред не осилил. Порекомендовал бы вынести информацию о блоках (те заголовки по 4 байта) один раз вынести в отдельный файл кэша, а потом использовать по необходимости этот кэш.

Maurog

да, нфс-это жирное слово
какие есть советы по этому поводу?:)
могу попробывать на локальном диске тест прогнать
уже однажды гонял: 2.5 минуты считывания вместо 4-5
под линукс xeon.

sergey_m

>> затем блоками в 30Мб - 6 секунд.
> 280 мегабайт в секунду? Молодой человек, вы что-то не договариваете. Таких винтов небывает.
У него NFS. Так что там столько слоёв кэширования, что со счёту собьешься их считать.

Marinavo_0507

> какие есть советы по этому поводу?:)
хм
уменьшать количество удалённых запросов
нормальный совет?

Maurog

нет
плохой

Maurog

можно попробывать отвлечься от нфс (хотя у нас все на нем) и сделать шустрость на локальном линуксе.
как ускорить эти 2.5 минуты?

sergey_m

Ты можешь привести не фрагмент тестовой программы, а программу полностью? Ту самую, которая блоками по 200 байт читает 1.7Гб в течение 2.5 минут.

Dasar

интересно, несколько потоков замедлят доступ или ускорят..

sergey_m

> интересно, несколько потоков замедлят доступ или ускорят..
Вряд ли. Ускорить может aio (кстати уже упоминалось в этом треде). Например в FreeBSD aio выполняется в отдельном ядерном треде, не зависимом от данного процесса. Возможно в линукс так же.

Maurog

перед этим тестовым фрагментом вызывается только открытие файла:

filebuf fb;
fb.open(filename,ios::read|ios::binary)
istream InStream(&fb);

Maurog

насчет fread скажите чего-нить..
я бы прогнал тестик...
тредами не пользуемся вообще ;(
хотя и пускаем на 4-8 процессорных тачках обычно.

Dasar

если делать правильно - то для начала запусти профайлер - и посмотри где у тебя больше всего времени тратится
причем проверять стоит со сброшенным кэшом (сначала запускаешь чтение каких-нибудь других больших файлов)

Maurog

ясно
очередной бесполезный тред.
можно в мусорку скидывать.

sergey_m

> перед этим тестовым фрагментом вызывается только открытие файла:
Извини, я в этом языке ничего не понимаю. Мне нужна рабочая тестовая программка, которая просто компилится и работает.
Вот такую программку сделал я:

#include <sys/types.h>
#include <sys/uio.h>
#include <err.h>
#include <fcntl.h>
#include <unistd.h>
#define BUFSIZE 200
int
main(int argc, char **argv)
{
char buf[BUFSIZE];
int nread, fd;
if (argc < 2)
errx(1, "argument required");
if fd = open(argv[1], O_RDONLY < 1)
err(1, "can't open %s", argv[1]);
while nread = read(fd, buf, BUFSIZE > 0)
;
if (nread != 0)
err(1, "read");
}

Локально она читает файл размером 1461585920 за 39.5 секунд, получается 37 Мбайт в секунду, что вполне похоже на скорость этого винта. То есть, несмотря на 200 байтовый буфер, скорость близка к скорости железа. Тестовый файл не читался ранее (с момента загрузки машины то есть кэширование исключено. Винт SATA, машина Athlon XP. Насколько понял я, у тебя более мощные машины.
Прямо сейчас у меня нет NFS сервера и клиента, между которыми гигабит, поэтому протестировать на NFS могу завтра, если тебе интересно.
P.S. Речь о операционной система FreeBSD.

Maurog

ты пользуешься другими функциями чтения файла.
я уже спросил, как еще можно считывать файл
я могу попробывать read делать без стримов на линуксе Xeon+nfs.
да и на локальном могу протестить.

sergey_m

ты пользуешься другими функциями чтения файла.
я уже спросил, как еще можно считывать файл
я могу попробывать read делать без стримов на линуксе Xeon+nfs.
да и на локальном могу протестить.
Твой плюсовый fread внутри себя тоже делает read(2). Любой высокоуровневый интерфейс в UNIX, который читает файлы, в глубине себя заканчивается или read(2) или mmap(2).

sergey_m

> Любой высокоуровневый интерфейс в UNIX, который читает файлы в глубине себя заканчивается или read(2) или mmap(2).
Или aio_read...

Maurog

ой..
fread делает read значит?....
ща протестю read

otets-mihail

он работает с ним через свой буфер

Maurog

я вставил подобный тест в самом начале своей тестовой функции ( с BUFSIZE 30Mb)
а) нфс: 94 сек и по 1.5 сек на остальные два теста
б) локально: 34 сек и по 2.5 сек на остальные.
 

mira-bella

Твой плюсовый fread внутри себя тоже делает read(2).
мама родная
fread - не плюсовый, это функция стандартной библиотеки C (ну и конечно в плюсах он тоже есть в качестве рудимента).

mira-bella

Наглая ложь(с).
Во-первых, в рассматриваемом случае в кэше окажется вообще всё - и стек, и код вызывающей функции, и код вызываемой, и локальные переменные обеих. И call будет исполняться за один такт. Причём безусловный call даже не будет скидывать конвеер.
во-первых: где ложь? Я что где-то писал, что все что надо не может быть закешировано?
Во-вторых: когда приводишь тирады в этом духе и разного рода сильные заявления типа "call будет исполняться за один такт", надо указывать как минимум ядро проца к которому это относится и ситуацию, в которой это верно. Уж не будешь ли ты утверждать, что всякий call выполняется за один такт? Как минимум вызываемую функцию когда-то надо закешировать впервые (что может конечно произойти и заранее параллельно выполнению, а может и не произойти, например потому что текущее выполнение осуществляет доступ к памяти, занимая шину). А что если очень часто происходят call-ы функций раскиданных по всей оперативке? Тоже все и всегда за 1 такт? Гы гы.
Во-вторых, задержки по доступу к винту превышают возможные задержки на вызовах функций эдак на шесть десятичных порядков. В миллион раз, то есть. Миллисекунды против наносекунд. И есть некоторая надежда, что выставление правильного размера буфера непосредственно у файла позволит оси оптимизировать именно эти, большие задержки. Например, будет более правильно использоваться внутренний буфер винта.
это все понятно.
но к чему это вообще написано?
Тонкости реализации кеширования ядром ОС доступа к устройствам мы вроде не обсуждали в этом треде.

mira-bella

fread делает read значит?....
ща протестю read
это правда что ли открытие?
read - это системный вызов
ясно, что все функции доступа к файловой системе работают через системные вызовы
Разница в том, что fstream (который тоже работает через read/write/прочее на юниксах) - это средство стандартной библиотеки C++, а значит оно работать будет везде, а не только на юниксе, как системные вызовы юникса.
Тоже касается и fread который есть функция стандартной библиотеки C. fread - это C-функция, и использовать ее в C++ проге - полное извращение.
FILE (C) и fstream(C++) имеют еще внутреннюю буферизацию (которую можно отключить) - не путать с кешированием системой ввода-вывода ОС.
Если использовать собственную буферизацию, то библиотечную буферизацию (FILE/fstream) разумно отключить.
А вообще насколько я понял у тебя узким местом является доступ к файлу, так что можно особо не заморачиваться над оптимизацией использования ресурсов процессора.
PS: если хочешь оптимальной производительности, не жертвуя портируемостью, то пиши целиком на C, используя стандартную библиотеку (там где ее достаточно). А если пишешь на плюсах, то пиши наиболее логично и читабельно и забей на эти измерения.

sergey_m

я вставил подобный тест в самом начале своей тестовой функции ( с BUFSIZE 30Mb)
а) нфс: 94 сек и по 1.5 сек на остальные два теста
б) локально: 34 сек и по 2.5 сек на остальные.
Чёрт возьми, тебя тяжело понять. Какой подобный тест? Просто покажи свою программу в таком виде, какую ты использовал. Проще показать код, чем описывать внесённые изменения словами.
Да и в результатах тоже лучше приводить не только время, но и размер считанного файла. И очень важно читался ли файл до этого с момента ребута или нет.

Maurog

тесты, которые я имею в виду:
1) считывание истримом с буфером 200 байт
2) считывание истримом с буфером 30Мбайт
3) считывание твоим способом с помощью read буфером в 30Мбайт
для первых двух тестов я код написал. для третьего ты написал.
судя по выводу:
 
DBG: istream_read by 30Mbites bites:152.937; 58 blocks readed
  

размер файла 30 миллионов байт* 58 = 1740 миллионов байт (+/- 30Мбайт, последний блок имеет неполную длину).
более точно можно посчитать отсюда:
 
DBG: istream_read by 200 bites:162.556; 8607427 blocks readed
 

файл считывался много раз, однако я заметил, что при перезапуске всей проги кеш как будто очищается и первое чтение долго делается, остальные два быстро (я же написал вывод проги и времена).
линуксы и солярки у нас не перегружают. сам понимаешь.
зы: сорри фор май инглиш
нет слова readed =)
да и вообще:
с Наступающим Новым Годом!
всех)

sergey_m

Ну получается 10 Мб/с. У тебя NFS ходит по 100Мбитной сети? Вот ты и упёрся в её максимум.
Оставить комментарий
Имя или ник:
Комментарий: