Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2016.03.27;
Скачать: CL | DM;

Вниз

Много памяти   Найти похожие ветки 

 
dmk ©   (2014-08-30 11:19) [0]

Привет! Как гарантированно выделить скажем 4-10 гб оперативной памяти? Getmem AllocMem не всегда даже гигабайт выделяют. Нет памяти говорят и все, а в системе 24 Гб стоит. Нужно для обработки больших изображений.


 
junglecat   (2014-08-30 12:35) [1]

VirtualAlloc


 
Игорь Шевченко ©   (2014-08-30 13:03) [2]

"4-10 Гб" можно выделить в 64-битном приложении.


 
megavoid ©   (2014-08-30 14:30) [3]

Странно...

{$APPTYPE CONSOLE}
begin
 AllocMem(512 * 3 * 1024 * 1024);
 readln;
end.

Process explorer Руссиновича показывает 1576576kb private bytes, 2252kb working set, то есть выделило-таки.


 
junglecat   (2014-08-30 14:36) [4]

512 * 3 * 1024 * 1024 = ~1.6G
а dmk 4 надо


 
megavoid ©   (2014-08-30 15:49) [5]

Ну ээ, там NativeInt, ну вот можно так, биттэ:

{$APPTYPE CONSOLE}
type NativeInt = Int64;
var
 i: NativeInt;
begin
 i := 1024 * 1024 * 1024;
 i := i * 26;
 AllocMem(i);
 readln;
end.

http://i66.fastpic.ru/big/2014/0830/3d/9bdf2ac267d2588f7a14e4e2d940a33d.png


 
dmk ©   (2014-09-01 17:52) [6]

Не выходит каменный цветок.

FSize := FScLen * FHeight + (FScLen * 4);
FMemEntry := VirtualAlloc(nil, FSize, MEM_RESERVE, PAGE_READWRITE);

FMemEntry даже на файле больше 900 Мб уже всегда nil. Последняя системная ошибка #8. EOutOfMemory.


 
dmk ©   (2014-09-01 18:03) [7]

Photoshop CC открывает 4 Гб файл за 7-8 секунд. Как он это делает? Я даже гигабайт не могу выделить, а читалка тифов у меня поддерживает тифы любого размера. FSize 64 битный.
А может надо приложение как 64 бита компилировать?


 
MBo ©   (2014-09-01 18:34) [8]

>Как он это делает?
полосками

>А может надо приложение как 64 бита компилировать?
Если использовать большие куски памяти - то да, об этом в [2] сказали.


 
junglecat   (2014-09-01 19:51) [9]

> А может надо приложение как 64 бита компилировать?

ясен пень, указатель в 32-бит всяко больше 4Гб не адресует


 
Rouse_ ©   (2014-09-01 21:58) [10]


> dmk ©   (30.08.14 11:19) 
> Привет! Как гарантированно выделить скажем 4-10 гб оперативной
> памяти?

Гарантированно - никак. Память всегда фрагметированна, поэтому даже под 64 битами никто не может гарантировать в выделении последовательно идущего пула страниц.
Далее - может таки речь идет не о физической, а о виртуальной памяти? В этом случае все немного мягче проходит.
Ну а по поводу обработки изображений - никто не будет грузить в память битмапину в 4 гигабайта в память целиком. Зачем, если зная ее формат, мы можем работать с ней по кусочкам?


 
dmk ©   (2014-09-02 00:41) [11]

>никто не будет грузить в память битмапину в 4 гигабайта в память целиком
А надо!!! Памяти полно. Фотошоп же грузит. Жрет память много и не свопит на винт.


 
Rouse__   (2014-09-02 01:16) [12]

Удалено модератором


 
dmk ©   (2014-09-02 02:03) [13]

Немного разобрался. Вот пример на XE6:
Все нормально резервирует, но освобождать не торопиться.
Если несколько раз нажать кнопку, то следующий блок остается за процессом.
Как сию проблему решить? Может в VirtualFree чего не так указал?

unit MemMain64;

interface

uses
 Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
 Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Memo1: TMemo;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

Procedure ClearMem(Addr:UInt64; Size: UInt64);
asm
 push rcx
 push rbx

 mov rax, 0
 mov rdi, Addr
 mov rcx, Size
 shr rcx, 3

 @@c:
 mov [rdi], rax
 add rdi, 8
 loop @@c

 pop rbx
 pop rcx
end;

//..............................................................................

procedure TForm1.Button1Click(Sender: TObject);
var
 pMem: pointer;
 pSize: UInt64;
 Error: integer;
 msg: PWideChar;
 TotalTime, eSize: extended;
 StartTime, EndTime: DWord;

begin
 self.Button1.Enabled := false;

 pSize := UInt64(1024 * 1024 * 1024) * Random(10); //Гб
 eSize := pSize / 1024 / 1024 / 1024;

 pMem := VirtualAlloc(nil, pSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);

 if pMem = nil then
   begin
     Error := GetLastError();
     raise Exception.Create("Error Message: " + IntToStr(Error));
   end;

 Memo1.Lines.Clear;

 msg := PChar("Зарезервировано памяти: " + FloatToStrF(eSize, ffNumber, 18, 2 ) + " Гб");
 Memo1.Lines.Add(msg);

 //...
 Memo1.Lines.Add("Память заполняется нулями ...");
 StartTime := GetTickCount;
 ClearMem(UInt64(pMem), pSize);
 EndTime := GetTickCount;
 TotalTime := (EndTime - StartTime) / 1000;

 msg := PChar("Очищено " + FloatToStrF(eSize, ffNumber, 18, 2 ) + " Гб за " + FloatToStrF(TotalTime, ffNumber, 18, 2) + " сек");
 Memo1.Lines.Add(msg);

 //...
 VirtualFree(pMem, pSize, MEM_RELEASE or MEM_DECOMMIT);

 self.Button1.Enabled := true;
end;

end.


 
dmk ©   (2014-09-02 02:06) [14]

Работает кстати очень шустро :)


 
megavoid ©   (2014-09-02 12:30) [15]

А зачем mov [rdi], rax? Вроде VirtualAlloc делает сам: Memory allocated by this function is automatically initialized to zero, unless MEM_RESET is specified.


 
dmk ©   (2014-09-02 12:49) [16]

Да просто проба пера :)


 
dmk ©   (2014-09-02 22:39) [17]

Разобрался. Правильно так освобождать: VirtualFree(pMem, 0, MEM_RELEASE);

megavoid ©   (02.09.14 12:30) [15]
Заполняется нулями если стоит флаг MEM_COMMIT. Не всегда нужен.



Страницы: 1 вся ветка

Текущий архив: 2016.03.27;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.006 c
2-1409638456
leshka-m
2014-09-02 10:14
2016.03.27
Подключение к MySQL


2-1409644080
Юляшка
2014-09-02 11:48
2016.03.27
Новое окно TWebbrowser


15-1437140235
delphin1986
2015-07-17 16:37
2016.03.27
Функция проверки вхождения точки в многоугольник


15-1436909401
Юрий
2015-07-15 00:30
2016.03.27
С днем рождения ! 15 июля 2015 среда


15-1437484469
sniknik
2015-07-21 16:14
2016.03.27
Как включить пс спикер в Win7?