Linux-Bulgaria.ORG
навигация

 

начало

пощенски списък

архив на групата

семинари ...

документи

как да ...

 

 

Предишно писмо Следващо писмо Предишно по тема Следващо по тема По Дата По тема (thread)

Re: lug-bg: влияние на размера на блока


  • Subject: Re: lug-bg: влияние на размера на блока
  • From: Peter Pentchev <roam@xxxxxxxxxxx>
  • Date: Thu, 26 Aug 2004 12:50:44 +0300

On Thu, Aug 26, 2004 at 11:06:03AM +0300, George Danchev wrote:
> On Wednesday 25 August 2004 15:14, Peter Pentchev wrote:
> > On Wed, Aug 25, 2004 at 02:53:42PM +0300, George Danchev wrote:
> > > On Wednesday 25 August 2004 13:17, Peter Pentchev wrote:
> > > --cut--
> > >
> > > > Какво точно искаш да кажеш с това 'да получи на вход'?  Ако имаш
> > > > предвид да се даде на tar опция -b 1800, така че то да прави write() на
> > > > парчета от 900KB и bzip2 да получава по 900KB при всеки read(), аз
> > > > виждам два възможни сериозни проблема с това:
> > >
> > > Мда, точно така, не виждам нищо лошо в:
> > > tar cf - dir -b 1800 | bzip2 > dir.tar.bz2
> >
> > Значи да попитам пак: смяташ, че ако размерът на изходния блок на tar е
> > равен на размера на входния блок на bzip2, това ще доведе до повишаване
> > на производителността, така ли?  Един малко тъп въпрос: защо?  Т.е. как?
> > Т.е. какво точно смяташ, че ще се подобри?
> 
> ами точно както си си отговорил по-долу, имах предвид да се намали сискол 
> овърхеда от реблокинг при bzip2.

Мдаааа... оказа се, че майтапът е пълен; виж по-долу относно начина,
по който bzip2 всъщност чете :)))

> > Единственото, което на мен ми се струва възможно да се подобри, е това
> > bzip2 да си получава входа с по-малко работа, т.е. с по-малко syscalls,
> > т.е. да получава по 900KB (или по-точно по 899981 байта) при всяко
> > извикване на read() - а това е *точно* това, което смятам, че няма начин
> > да стане :)  Ако имаш някаква друга идея за това как точно ще се подобри
> > работата на bzip2, ако на tar му зададеш -b 1800, казвай!
> 
> имаме: block = [record size (кратно на 512)] x [blocking factor]
> това 899981 за сега нямам идея защо се получава, но се получава при разни 
> стойности на -b:

Това 899981 се получава от bzip2, няма нищо общо с tar.  В сорса на
bzip2, bzlib.c, функцията BZ2_bzCompressInit(), около ред 238:

   s->nblockMAX         = 100000 * blockSize100k - 19;

Това е unconditional, изобщо не зависи от това, което bzip2 много
по-късно ще прочете от входния си файл.  Размерът на блока, който bzip2
компресира, е 100000 байта * колкото си му казал - 19; така при 'колкото
си му казал' == 9 се получава точно 899981.

> Да се намали сискол овърхеда от реблокинг при bzip2. Това е
> единственото което можем да се опитаме да си спестим според мен.

Мда, и аз за това говоря наистина от самото начало, само че се оказва,
че ключът от бараката е на съвсем, ама съвсем друго място.. виж малко
по-долу.

> > > Според мен ядрото няма да бута в пайпа наведнъж всичките 899981 байта ;-)
> > > горната команда ще мине и на фрийсби, почти съм сигурен... просто тези
> > > 899981 байта ще бъдат подадени на по-малки части и това си е работа на
> > > ядрото мисля да контролира двата края на пайпа и колко влиза и колко
> > > излиза в и от тях.
> >
> > Така де, така - и точно затова ядрото и от двата края на пайпа не
> > поддържа блокове по 899981, следователно bzip2 няма начин да прочете
> > наведнъж 899981 байта - и с какво ще се подобри работата му тогава?
> > Особено при положение, че 1800 * 512 != 899981 :)
> 
> значи първо не сме сигурни дали tar и bzip2  write()-ват и read()-ват цели 
> блокове или цели записи или части от записи от по 512 байта.

За tar сме на практика сигурни, че write-ва блокове; нали това е цялата
идея на параметъра block size - че някои лентови устройства са си
истински block devices и могат да четат и пишат *само* на блокове, така
че единственият начин tar да успее изобщо да запише нещо е да подаде цял
блок в един write().

За bzip2... там се оказа странно :)  Сорса на bzip2, bzip2.c, функцията
compressStream(), около ред 444:

   while (True) {

      if (myfeof(stream)) break;
      nIbuf = fread ( ibuf, sizeof(UChar), 5000, stream );
      if (ferror(stream)) goto errhandler_io;
      if (nIbuf > 0) BZ2_bzWrite ( &bzerr, bzf, (void*)ibuf, nIbuf );
      if (bzerr != BZ_OK) goto errhandler;

   }

Най-важен е редът с nIbuf = fread(..., 1, 5000, ...) - оказва се, че
bzip2 използва stdio за четене, и си взима входа по 5000 байта наведнъж.
Разбира се, това не значи, че bzip2 чете по 5000 байта на syscall -
част от идеята на библиотеката stdio е да буферира и входа, и изхода,
така че всъщност четенето се прави на блокове с размер, указан в
стандартната константа BUFSIZ, дефинирана в stdio.h.  Разбира се, тази
стойност е различна за различните реализации на библиотеката stdio,
макар че изглежда, че за няколко различни варианта на Linux (всичките с
glibc) все е 8192.  Под FreeBSD пък се оказа 1024.

Демек, каквито и магии да правим с tar -b и bzip2 -1..9, всичко, което
bzip2 някога ще успее да направи със syscalls, ще бъде да чете по BUFSIZ
байта от входния пайп - BUFSIZ, ни повече, ни по-малко.  Оттук нататък
*може би* може да се постигне някакво ускорение, ако се опитаме да
убедим tar да подава по горе-долу толкова байта, но не съм много
сигурен: тогава пък може да се сблъскаме с буферирането на данни в
пайпове от самото ядро, което може да не позволи предаване на 8KB
наведнъж.  За FreeBSD може и да успее - ако има достатъчно памет и
mbufs, като нищо може да увеличи размера на пайпа и над 4KB, само че
това няма много смисъл, след като bzip2 ще чете само по 1KB.  За Linux
не съм много сигурен, но от това, което сега гледам в
arch/i386/kernel/sys_i386.c, fs/pipe.c и няколко header файла, изглежда,
че гаранция за атомично писане има при опит за писане на не повече от
4KB, а максималният размер на самия пайп е PAGE_SIZE, което при i386
според include/asm/page.h кажи-речи винаги е... ами.. таковата.. 4KB :)

Накратко, оптимизация на syscalls на bzip2 на практика не може да бъде
направена - не и при положение, че tar му подава всичко през пайп :(

> Та това може да не е размера на блока който получава bzip2, а който обработва 
> явно след реблокване. Предлагам да не гадеам повече. 

Надявам се, че горното малко разсея мъглата, макар и да достигна до
съвсем странни изводи :)

> Освен това, не е казано, че трябва двете приложения да се пайпват, ако имаме 
> съмнения, че предаването в пайпа може да се бави поради разни причини (tar 
> --options; bzip2 --options)

Единственият начин да не ги пайпваш е да направиш tar -cf fname.tar foo
и после отделно bzip2 -9 fname.tar.  При това ще избегнеш наистина
ограниченията, наложени от пайповете, но пък тогава вече няма да има
абсолютно никакво значение - ама наистина абсолютно никакво - какъв
размер на блок се избира за tar :)

Поздрави,
Петър

-- 
Peter Pentchev	roam@xxxxxxxxxxx    roam@xxxxxxxx    roam@xxxxxxxxxxx
PGP key:	http://people.FreeBSD.org/~roam/roam.key.asc
Key fingerprint	FDBA FD79 C26F 3C51 C95E  DF9E ED18 B68D 1619 4553
This sentence was in the past tense.

Attachment: pgptRDj0xmqV6.pgp
Description: PGP signature



 

наши приятели

 

линукс за българи
http://linux-bg.org

FSA-BG
http://fsa-bg.org

OpenFest
http://openfest.org

FreeBSD BG
http://bg-freebsd.org

KDE-BG
http://kde.fsa-bg.org/

Gnome-BG
http://gnome.cult.bg/

проект OpenFMI
http://openfmi.net

NetField Forum
http://netField.ludost.net/forum/

 

 

Linux-Bulgaria.ORG

Mailing list messages are © Copyright their authors.