Конференция "KOL" » Stream2Stream на АСМе? [Delphi, Windows]
 
  • andreil © (20.03.08 17:56) [0]
    Никто не знает, где такое можно найти? А то всю работу тормозит, тк работа идет только с кусочками по 8Кб, большие нельзя - а вдруг попадешь на фрагментированный кусок, тогда будет плохо ;) Если сделать этоже чтение блоками по 512Кб, скорость сразу нормальная, до максимума (20Мб/с), а так - 800Кб/с :(
  • Palladin © (20.03.08 18:41) [1]
    если ты про все тоже копирование файлов, то "крутые" парни делают это через CopyFile
  • andreil © (20.03.08 19:48) [2]
    Мне надо не копирование файла, а "чтение части файла с записью в другой файл", тк в одном входном файле находится много (до 200тас) файлов ;)
  • exero (20.03.08 20:08) [3]
    Боюсь тебе никакой asm не поможет.... Рулит не asm, а грамотные алгоритмы.
  • andreil © (20.03.08 20:24) [4]
    алгоритм - простой цикл, в нем вначале узнаем, с какого сектора читать, потом само чтение и потом - внешние признаки работы (прогрессбар двигается, счетчик тикает и тп). Если закоментировать строку с "Stream2Stream", то скорость ограничивается скоростью процессора, но работы программы нету :(
  • Dimaxx © (21.03.08 01:25) [5]

    > работа идет только с кусочками по 8Кб, большие нельзя -
    > а вдруг попадешь на фрагментированный кусок

    Откуда этот бред? Вот в таком режиме у тебя скорость и будет минимальная. Копируй кусками 512 кб раз скорость нормальная.
  • exero © (21.03.08 11:19) [6]
    2 andreil еще раз повторяю тормозит не Stream2Stream, a твой способ. Хоть иногда слушай, что другие говорят.
  • andreil © (21.03.08 13:09) [7]
    Кусками по 512 кб НЕЛЬЗЯ, тк файлы ФРАГМЕНТИРОВАННЫЕ, и если буду читать кусками по 512Кб, то на выходе получатся битые файлы!!!!!!
  • mdw © (21.03.08 13:24) [8]

    > Кусками по 512 кб НЕЛЬЗЯ, тк файлы ФРАГМЕНТИРОВАННЫЕ, и
    > если буду читать кусками по 512Кб, то на выходе получатся
    > битые файлы!!!!!!

    Бред. Тему можно закрывать, хочется человеку фигней заниматься, пускай.
  • andreil © (21.03.08 13:36) [9]

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

    Не знаешь, с какими файлами я работаю, не лезь. Я уже изучил с 0 прочти весь формат файлов GCF (Steam), но все дело стопорится на скорости чтения.
  • Palladin © (21.03.08 15:15) [10]

    > Кусками по 512 кб НЕЛЬЗЯ, тк файлы ФРАГМЕНТИРОВАННЫЕ,

    расскажи мне пожалуйста, что такое ФРАГМЕНТИРОВАННЫЕ файлы... просвяти старика...
  • =BuckLr= © (21.03.08 16:32) [11]
    Думаеццо, винт не пластинка, стало быть, потоку по барабану, фрагментированы файлы, или нет. Битые файлы получаются, скорее всего, из-за твоего алгоритма. Исходник, что ли, выложи...
  • andreil © (22.03.08 09:46) [12]
    Вот сырцы -http://ifolder.ru/5832852. Если разберетесь, то можете помочь :)
    ЗЫ: Тормоз находится в строке 676 (или около того).

    ЗЫЫ: А фрагментация там выражена тем, что есть таблицы секторов для каждого файла. Размер одного сектора - 8Кб. А в таблице секторов нередко встречаются вот такие вот случаи:
    SectorsTable[FileHandle]=(300, 4, 46, 35, ....)


    Так что чтение кусками более 8Кб часто приводит к битию файлов :(
  • Dimaxx © (22.03.08 12:59) [13]
    Тогда тебе надо читать свои куски в memorystream, а потом разом записывать все это в файл.
  • andreil © (22.03.08 15:18) [14]
    Это я уже пробовал. Работает чуть быстрее, но представь себе ситуаций, когда распаковывается файл на 60Мб - работать будут еще дольше.
    Я сделал так: считываем кусочками по 8Кб до заполнения буфера (256Кб) либо до конца файла, затем сбрасываем буфер на диск. Итого - скорость выросла до 7Мб/с на самых запаренных участках, а было около 1-2Мб/с. К примеру, распаковка 13Гб файлов, фрагментация которых была намного выше среднего (слишком много обновлений :( ) длилиась всего 40минут со средней скоростью 9Мб/с (правда должна быть 25Мб/с - предел моего винчестера).
  • MTsv DN (22.03.08 15:52) [15]
    Я понимаю так:
    1. Если Вы читаете по 512 кБ, то все в норме (я имею в виду скорость) Условно обозначим число вызовов Stream2Stream = Х, также Х - это число обращений к диску...
    2. Если Вы читаете по 8 кБ то получается Х*64 (относительно п.1) вызовов Stream2Stream и обращений - естесссна скорость упала...
    3. Если вы забиваете буфер до 256 кБ, то Х*2 (относительно п.1) - вызовов Stream2Stream и X*64 (относительно п.1) - обращений к диску - и скорость возросла...по-моему это доказывает, что Stream2Stream работает как надо, а вот снижение скорости результат постоянного обращения к диску...что в принципе тоже понятно...

    Попробуйте буфер забивать до 512 кБ и сравните скорости - это раз...
    Попробуйте отключить визуальные эффекты типа обновление PB и прочего...и сравните скорость...
    Попробуйте разбить считывание на 2 потока...
  • exero (22.03.08 16:07) [16]
    Ну и кто виноват )) Stream2Stream или корявый алгоритм )). По моему скорость будет увеличиваться с  ростом буфера.
  • andreil © (22.03.08 16:21) [17]

    > Попробуйте разбить считывание на 2 потока...

    Знал бы как, разбил бы
  • MTsv DN (22.03.08 17:19) [18]
     TForm1=...
     public
      function ReadThread1Execute(Sender: PThread): Integer;
      function ReadThread2Execute(Sender: PThread): Integer;
     end;

    var
     ReadThread1, ReadThread2 : PThread;
    ...
    function TForm1.ReadThread1Execute(Sender: PThread): Integer;
    var
    S : PStream;
    begin
    S := NewReadFileStream('blablabla.gfc');
    S.Position := 0;
    цикл отS.Position до определенного места файла;

    Free_And_Nil(S);
    ReadThread1.Terminate;
    end;

    function TForm1.ReadThread2Execute(Sender: PThread): Integer;
    var
    S : PStream;
    begin
    S := NewReadFileStream('blablabla.gfc');
    S.Position := определенное место файла;
    цикл от S.Position до конца файла;
    Free_And_Nil(S);
    ReadThread2.Terminate;
    end;

    procedure TForm1.Button1Click(Sender: PControl);
    begin
    ReadThread1 := NewThreadAutoFree(Form1.ReadThread1Execute);
    ReadThread2 := NewThreadAutoFree(Form1.ReadThread2Execute);
    ReadThread1.Resume;
    ReadThread2.Resume;
    repeat
     ReadThread1.WaitForTime(1000);
    until ReadThread1.Terminated and ReadThread2.Terminated;
    Free_And_Nil(ReadThread2);
    Free_And_Nil(ReadThread1);
    end;



    Ну, попробуй это... Хотя хрен знает будет работать или нет...
  • MTsv DN (22.03.08 17:50) [19]
    TForm1=...
    public
     function ReadThread1Execute(Sender: PThread): Integer;
     function ReadThread2Execute(Sender: PThread): Integer;
    end;

    var
    ReadThread1, ReadThread2 : PThread;
    R1Stop, R2Stop : boolean;

    function TForm1.ReadThread1Execute(Sender: PThread): Integer;
    begin
    pb1.MaxProgress := 1000;
    pb1.Progress := 0;
    repeat
     Form1.pb1.Progress := Form1.pb1.Progress + 1;
     Form1.pb1.ProcessMessages;
    until Form1.pb1.Progress >=  Form1.pb1.MaxProgress;

    R1Stop := true;
    ReadThread1.Terminate;
    end;

    function TForm1.ReadThread2Execute(Sender: PThread): Integer;
    begin
    pb2.MaxProgress := 10000;
    pb2.Progress := 0;
    repeat
     pb2.Progress := pb2.Progress + 1;
     pb2.ProcessMessages;
    until pb2.Progress = pb2.MaxProgress;

    R2Stop := true;
    ReadThread2.Terminate;
    end;

    procedure TForm1.Button1Click(Sender: PObj);
    begin
    R1Stop := false;
    R2Stop := false;
    ReadThread1 := NewThreadEx(Form1.ReadThread1Execute);
    ReadThread1.Resume;

    ReadThread2 := NewThreadEx(Form1.ReadThread2Execute);
    ReadThread2.Resume;
    repeat
     Form1.Form.ProcessMessages;
    until R1Stop and R2Stop;
    Free_And_Nil(ReadThread2);
    Free_And_Nil(ReadThread1);
    end;


    Вот так работает... Мне правда не нравится:
    repeat
     Form1.Form.ProcessMessages;
    until R1Stop and R2Stop;


    Но ничего повеселее я придумать не смог...
 
Конференция "KOL" » Stream2Stream на АСМе? [Delphi, Windows]
Есть новые Нет новых   [134431   +15][b:0][p:0.002]