2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2, 3, 4, 5  След.
 
 Re: Чем обработать 8 Гб данных?
Сообщение02.05.2021, 20:29 


24/10/14
46
Любопытно... Подобные задачи как у автора, решаются в геофизике. Программы на С , были и в Delphi. При таких объемах , инфа в файлах записного типа - акустика к примеру . Видел кусок прг для обработки акустики - там даже ассемблерные вставки были для скорости. Методы обработки , как указал пользователь "realeugene".
В тексте (конкретно .las формат) пишут файлы помельче - порядка десятков тысяч записей.
Какие-то мелкие задачи, типа подсчета значений некой функции в каждой точке в текстовом файле , я делал даже в basic Excel и именно способом указанным "realeugene" :)))

 Профиль  
                  
 
 Re: Чем обработать 8 Гб данных?
Сообщение02.05.2021, 20:49 
Заслуженный участник


12/07/07
4448
photon, а чем проще?
Я создал файл с целыми от 1 до 400000000 и со случайно распределёнными значениями функции от 0 до 1 (но это не важно). А затем считал и нашёл минимальное, максимальное, среднее и выборочное стандартное отклонение. (Borland) Delphi 5 (Эта версия 32-битная.)
код: [ скачать ] [ спрятать ]
Используется синтаксис Delphi
var f, min, max, M, S: Double;
    i: LongInt;
    txt: Text;
begin
 Assign(txt, 'data.txt');
 Reset(txt);
 M:= 0;      S:= 0;
 min:= 1/0;  max:= -1/0;
 i:= 0;
 while not EoF(txt)
  do begin
       inc(i);
       readln(txt, i, f);
       M:=M + f;
       if f < min
        then min:= f
        else if f > max then max := f;
       S:= S + sqr(f);
     end;
 Close(txt);
 Assign(txt, 'res.txt');
 Rewrite(txt);
 M := M/i;
 S := S/i - sqr(M);
 Writeln(txt, 'M=', M, ' min=', min, ' max=', max, ' S=', S);
 Close(txt);
end.

Запустил и, пока отошёл на кухню поставить чайник и вернулся, уже файл на 14008M был обработан:
Код:
M= 4.99989748928722E-0001 min= 2.32830643653870E-0010 max= 9.99999998603016E-0001 S= 8.33274108211802E-0002
Нахождение списка и запись в фал этого списка при втором чтении исходного файла с данными займёт, конечно, время. Но ненамного больше. Если нужно часто обрабатывать подобные файлы, то, если есть возможность, то лучше писать такие длинные файлы не в текстовые, а в двоичные: не будет тратиться время на преобразование из текстового в двоичное представление.
destructor в сообщении #1516478 писал(а):
там даже ассемблерные вставки были для скорости
Время тратится на чтение данных. Даже в DOS играми на асме при работе с винчестером баловались в крайнем случае. Вместо этого старались просто выполнить дефрагментацию и читать большой файл с одного диска, а писать результат на другой.

 Профиль  
                  
 
 Re: Чем обработать 8 Гб данных?
Сообщение02.05.2021, 21:21 
Экс-модератор
Аватара пользователя


23/12/05
12047
GAA в сообщении #1516486 писал(а):
photon, а чем проще?

Думаю, поиском заданных интервалов.
Atom001 в сообщении #1516389 писал(а):
локальные максимум и минимум на заданных интервалах

 Профиль  
                  
 
 Re: Чем обработать 8 Гб данных?
Сообщение02.05.2021, 22:00 
Заслуженный участник


12/07/07
4448
Так интервалы по условию, вроде, заданы. Просто читаем из файла с заданием или стандартного ввода начало и конец интервала/интервалов и когда проходим при чтении файла с данными через соответствующие значения аргумента дополнительно ищем минимальное и максимальное значение функции.
Тут даже одного чтения файла с данными достаточно. Если же какая-то обработка статистическая нужна, то фиг его знает: ТС точную формулировку задачи в начальном сообщении не привёл.

Upd. Я бы не файл резал, а попробовал бы читать не по два числа, а большими блоками. (Если файл будет действительно большим.)

 Профиль  
                  
 
 Re: Чем обработать 8 Гб данных?
Сообщение02.05.2021, 23:11 


27/08/16
9426
GAA в сообщении #1516486 писал(а):
Вместо этого старались просто выполнить дефрагментацию и читать большой файл с одного диска, а писать результат на другой.
На SSD это не нужно.

-- 02.05.2021, 23:17 --

photon в сообщении #1516495 писал(а):
Думаю, поиском заданных интервалов.
Достаточно скинуть плавающие в бинарный файл, и тогда переход к нужному отсчёту будет мгновенным через fseek.Но мне кажется, что тут идёт домысливание задачи ТС. Ему не нужно писать универсальную систему обработки таких файлов или учиться нормально программировать скорее всего. Он не жалуется на скорость обработки. Значит, его разовую задачу ему нужно решать максимально просто.

UPD нужно использовать 64-битные целые в качестве смещений в файле и соответствующую функцию поиска: https://docs.microsoft.com/en-us/cpp/c- ... k-fseeki64
Под Линуксом long int и так 64-битный, но лучше сначала проверить для конкретного компилятора. напечатав sizeof(long).

 Профиль  
                  
 
 Re: Чем обработать 8 Гб данных?
Сообщение02.05.2021, 23:29 
Заслуженный участник


12/07/07
4448
GAA в сообщении #1516486 писал(а):
Даже в DOS играми на асме при работе с винчестером баловались в крайнем случае. Вместо этого старались просто выполнить дефрагментацию и читать большой файл с одного диска, а писать результат на другой.

realeugene в сообщении #1516503 писал(а):
На SSD это не нужно.
SSD во времена DOS. 30 лет назад. :) Сильно! :)

 Профиль  
                  
 
 Re: Чем обработать 8 Гб данных?
Сообщение02.05.2021, 23:31 


27/08/16
9426
GAA в сообщении #1516505 писал(а):
SSD во времена DOS. 30 лет назад. :) Сильно! :)
Ну а сейчас уже не времена DOS.

 Профиль  
                  
 
 Re: Чем обработать 8 Гб данных?
Сообщение02.05.2021, 23:39 
Заслуженный участник


12/07/07
4448
Конечно, и я уже лет так 30 не видел, чтобы для увеличения скорости на асме винтом управляли :)
Но это уже клинический оффтопик. На файлах такого малого размера на обычном винчестере (7200 об/мин) всё быстро выполняется, даже быстрый винт не нужен. Но конечно желать можно и большего. :)

Upd
realeugene в сообщении #1516503 писал(а):
UPD нужно использовать 64-битные целые в качестве смещений в файле и соответствующую функцию поиска: https://docs../fseek-fseeki64
Под Линуксом long int и так 64-битный, но лучше сначала проверить для конкретного компилятора. напечатав sizeof(long).
Да, желательно проверить для конкретного компилятора. В Borland Delphi Longint 32 битное. В Embarcadero Delphi Integer — 32-битное и для 32-битного кода, и для 64-битного:
procedure Seek(var F: File; N: Integer)
Integer represents a subset of the integer numbers. The range for the Integer type is from -2147483648 through 2147483647.
The size of Integer is 32 bits across all 64-bit and 32-bit platforms.
LongInt represents a subset of the natural numbers. LongInt size and range depend on the target platform:
On 32-bit platforms and 64-bit Windows platforms, LongInt is an 4-byte signed integer with the range [-2147483648 .. 2147483647]. ($-2^{-31}$ through $2^{32}-1$).
Note: 32-bit platforms include 32-bit Windows, 32-bit macOS, 32-bit iOS, and Android.
On 64-bit POSIX platforms (iOS and Linux), LongInt is an 8-byte signed integer with the range [-9223372036854775808 .. 9223372036854775807] ($-2^{63}$ through $2^{63}-1$).
$2^{32}-1$ — это опечатка в справке в Сети.
procedure Seek(var f: file; Pos: Int64)
type Longint =- 2147483648..2147483647
Но справке ни Embarcadero, ни freepascal я особо не верю. С Embarcadero влетал. :) Надо проверять. :)

 Профиль  
                  
 
 Re: Чем обработать 8 Гб данных?
Сообщение03.05.2021, 00:41 
Заслуженный участник


20/08/14
11155
Россия, Москва

(Похвастаюсь, 8ГБ это фигня)

Подумаешь 8ГБ, я год назад обработал почти 9ТБ двоичных данных (или более 22.4трлн символов/чисел). И скорость ограничивалась лишь скоростью чтения с диска и скачивания этих файлов из облака по 84ГБ каждый. Читал 4МБ данных (кратно одной порции упакованных данных) в буфер и разбирал его, потом читал следующую порцию, и по кругу, даже параллелить чтение и обработку поленился, скорость обработки была на порядок выше скорости чтения диска. Всё это было на 32 бит дельфи с асм вставкой в основном цикле обработки, но и без последней скорость обработки превышала скорость чтения диска (200МБ/с).

 Профиль  
                  
 
 Re: Чем обработать 8 Гб данных?
Сообщение03.05.2021, 01:44 


27/08/16
9426
GAA в сообщении #1516507 писал(а):
Да, желательно проверить для конкретного компилятора. В Borland Delphi Longint 32 битное. В Embarcadero Delphi Integer — 32-битное и для 32-битного кода, и для 64-битного:
В Паскале может быть всё иначе. Про GCC пишут, что на 64-битных системах long int 64-битный, но я сам не проверял.

 Профиль  
                  
 
 Re: Чем обработать 8 Гб данных?
Сообщение03.05.2021, 01:59 
Заслуженный участник


09/05/12
25179
realeugene в сообщении #1516512 писал(а):
В Паскале может быть всё иначе.
У FPC (и вроде у всех прочих так же) longint 32-битный, зато есть int64 и qword (второй - беззнаковый).
realeugene в сообщении #1516512 писал(а):
Про GCC пишут, что на 64-битных системах long int 64-битный, но я сам не проверял.
Это действительно так.

 Профиль  
                  
 
 Re: Чем обработать 8 Гб данных?
Сообщение03.05.2021, 02:31 
Заслуженный участник


12/07/07
4448
Pphantom в сообщении #1516513 писал(а):
(и вроде у всех прочих так же)
Боюсь от компилятора зависит. Не говоря об Embarcadero Delphi под Linux, например в GNU Pascal:
Код:
signed        unsigned        also unsigned     GNU C equivalent    size in bits (example)
ByteInt       ByteCard        Byte               [un]signed char            8
ShortInt      ShortCard       ShortWord         [unsigned]short int         16
CInteger      CCardinal       CWord              [unsigned]int              32
MedInt        MedCard         MedWord          [unsigned]long int           32
LongInt       LongCard        LongWord         [unsigned]long long int      64
Но дело не столько в этом, а в том, что номер записи в Seek в Borland/Embarcadero 32-битное, а в FPC-64 битное.
Borland Delphi 5 RTL seek.asm:
код: [ скачать ] [ спрятать ]
Используется синтаксис ASM
; *******************************************************
; *                                                     *
; *     Delphi Runtime Library                          *
; *                                                     *
; *     Copyright (c) 1996,98 Inprise Corporation       *
; *                                                     *
; *******************************************************

        INCLUDE SE.ASM
        INCLUDE FILEIO.ASM

        .386
        .MODEL  FLAT

        EXTRN   SetFilePointer:NEAR, GetLastError:NEAR, SetInOutRes:NEAR
        EXTRN   InOutError:NEAR

        PUBLIC  _Seek

        .CODE

;       PROCEDURE _Seek( f: File; recNum: Longint );

_Seek   PROC

; ->    EAX     Pointer to file variable
;       EDX     Record number

        MOV     ECX,EAX
        MOV     EAX,[ECX].Mode          ; check whether file is open
        SUB     EAX,fmInput
        CMP     EAX,fmInOut-fmInput
        JA      @@fileNotOpen

;       SetFilePointer(f.Handle, recNum*f.RecSize, FILE_BEGIN

        PUSH    FILE_BEGIN              ; pass dwMoveMethod
        MOV     EAX,[ECX].RecSize
        MUL     EDX
        PUSH    0                       ; pass lpDistanceToMoveHigh
        PUSH    EAX                     ; pass lDistanceToMove
        PUSH    [ECX].Handle            ; pass hFile
        CALL    SetFilePointer          ; get current position
        INC     EAX
        JZ      InOutError

@@exit:
        RET

@@fileNotOpen:
        MOV     EAX,103
        JMP     SetInOutRes

_Seek   ENDP

        END
 

 Профиль  
                  
 
 Re: Чем обработать 8 Гб данных?
Сообщение03.05.2021, 03:05 
Заслуженный участник


20/08/14
11155
Россия, Москва
Проблема не в 32 бит номере записи, можно же запись сделать 32КБ (или даже 1ГБ), а в команде push 0 вместо push edx при вызове SetFilePointer. Но при очень большом желании никто не мешает вызвать любую WinAPI функцию напрямую, да хоть ту же SetFilePointer и передать ей правильное 64 бит смещение. Конечно это танцы с бубном и не для слабонервных, но всё же возможно ...

 Профиль  
                  
 
 Re: Чем обработать 8 Гб данных?
Сообщение03.05.2021, 03:12 
Заслуженный участник


12/07/07
4448
А для слабонервных перейти на более позднюю версию Delphi.
RAD Studio XE7 Выдержка из файла \source\RTL\sys\system.pas:
код: [ скачать ] [ спрятать ]
Используется синтаксис Delphi
procedure _Seek(var f: TFileRec; recNum: Cardinal);
{$IFDEF MSWINDOWS}
{$IFDEF PUREPASCAL}
var
  Val64: UInt64;
  Val32Low: UInt32;
  Val32High: UInt32;
  Res: LongInt;
begin
  if (f.Mode >= fmInput) and (f.Mode <= fmInOut) then
  begin
    Val64 := UInt64(recNum) * f.RecSize;
    Val32High := UInt32(Val64 shr 32);
    Val32Low := UInt32(Val64);

    Res := SetFilePointer(f.Handle, Val32Low, @Val32High, FILE_BEGIN);
    if Res = -1 then InOutError()
    else
      if Res < 0 then SetInOutRes(131);
    //if Longint(SetFilePointer(f.Handle, Val32Low, @Val32High, FILE_BEGIN)) = -1 then
    //  InOutError();

  end else
    SetInOutRes(103);
end;
{$ELSE !PUREPASCAL}
{$IFDEF CPUX86}
asm
// -> EAX Pointer to file variable
//    EDX Record number

        MOV      ECX,EAX
        MOVZX    EAX,[EAX].TFileRec.Mode // check whether file is open
        SUB      EAX,fmInput
        CMP      EAX,fmInOut-fmInput
        JA       @@fileNotOpen

//  SetFilePointer(f.Handle, recNum*f.RecSize, FILE_BEGIN)
        PUSH     FILE_BEGIN    // pass dwMoveMethod
        MOV      EAX,[ECX].TFileRec.RecSize
        MUL      EDX
        PUSH     0           // pass lpDistanceToMoveHigh
        PUSH     EAX           // pass lDistanceToMove
        PUSH     [ECX].TFileRec.Handle   // pass hFile
        CALL     SetFilePointer          // get current position
        INC      EAX
        JZ       InOutError
        JMP      @@exit

@@fileNotOpen:
        MOV      EAX,103
        JMP      SetInOutRes

@@exit:
end;
{$ENDIF CPUX86}
{$ENDIF !PUREPASCAL}
{$ENDIF MSWINDOWS}
{$IFDEF POSIX}
begin
  if (f.Mode >= fmInput) and (f.Mode <= fmInOut) then
  begin
    if Longint(recNum) < 0 then  // Match windows behaviour. Only 0 .. MaxInt sizes are allowed.
      SetInOutRes(131)           // Negative seeks are dissablowed.
    else
                                                 
      if lseek(f.Handle, f.RecSize * recNum, SEEK_SET) = -1 then
        InOutError;
  end
  else
    SetInOutRes(103);
end;
{$ENDIF POSIX}
Upd Или попробовать воспользоваться функциями из Sysutils:
function FileSeek(Handle: Integer; const Offset: Int64; Origin: Integer): Int64; overload;
На форумах в Сети раньше писали, что на NTFS FileSeek вроде не работает файлами длиннее 4ГБ. В Delphi 5 у меня работает. Я запускал программу на файле с длиной больше $2^{32}$ и функция FileSeek переносила указатель в конец файла.
Используется синтаксис Delphi
Uses SysUtils;
var
 Hendle: Integer;
 Result: Int64;
begin
 Hendle:= FileOpen('r2013b.iso', fmOpenRead);
 Result:= FileSeek(Hendle, 7249258496, 0);
 writeln('Size=', Result);
 FileClose(Hendle);
end.
Программы выводила Size=7249258496.

-- Пн 03.05.2021 02:15:55 --

Dmitriy40 в сообщении #1516515 писал(а):
можно же запись сделать 32КБ (или даже 1ГБ)
Это не всегда удобно. Можно не до конца нетипизированный файл прочитать, или я уже забыл всё?

 Профиль  
                  
 
 Re: Чем обработать 8 Гб данных?
Сообщение03.05.2021, 04:33 
Заслуженный участник


20/08/14
11155
Россия, Москва
Ну раз есть FileSeek с int64 смещением, то проблемы нет и записи не нужны.
Насчёт читать не полную запись, если я правильно понимаю (что размер записи влияет лишь на адресацию внутри файла, функции же чтения/записи ровно те же), то попытка прочитать последнюю неполную запись просто прочитает сколько реально есть. А вот seek сделать точно на конец файла чтобы его дописать может и не получится (особенно если не пользоваться смещением от конца файла). Впрочем это всё давно не актуально.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 70 ]  На страницу Пред.  1, 2, 3, 4, 5  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group