Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.12.2017, 11:26   #1
artems67
Пользователь
 
Регистрация: 17.11.2015
Сообщений: 62
Восклицание Работа с ОЗУ (Delphi)

Добрый день,

ТЗ: Измерить скорости чтения блоков данных из ОЗУ

Я решил реализовывать это через проецируемый в память файл. То есть пользователь указывает кол-во элементов для записи в файл. Реализуется заполнение файла проецируемого в память random элементами, кол-во которых указал пользователь. + Идёт подсчёт времени процесса записи в файл.

Но почитав, я узнал, что при использовании FileMapping используется виртуальная память системы. То есть как я понял может быть задействована память, резервируемая операционной системой на жестком диске, а не только ОЗУ. И получается я работаю не чисто с ОЗУ ?

Собственно нужна помощь в понимании, как задействовать в работе только ОЗУ ?

Ниже ссылка на архив с моим проектом.



Моя программа:


Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, Spin,
  Menus;

type
  TForm1 = class(TForm)
    btMem: TButton; // Кнопка тест
    pb: TProgressBar;   // Bar прогресса
    se: TSpinEdit;  // Для указания кол-ва записи элементов
    IbMem: TLabel; // Отображает время
    Label3: TLabel;
    Label1: TLabel;
    Label2: TLabel;
    MainMenu1: TMainMenu;
    N1: TMenuItem;
    procedure btMemClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btMemClick(Sender: TObject);

 // Создаю файл методом его отоброжения

type PReal = ^Real;

var

 HFile, HMap: THandle;

 AdrBase, AdrReal: PReal;

 k: Integer;

 FSize: Cardinal;

 BegTime: TDateTime;

begin

 BegTime := Time; // Фиксирую время пуска

 // Подготовка ProgressBar:

 pb.Max := se.Value;

 pb.Position := 0;

 pb.Show;

 FSize := se.Value * SizeOf(Real); // Длина файла

 HFile := FileCreate('test1.dat'); // Создаю файл

 if HFile = 0 then //  Обработка исключения

  raise Exception.Create('Ошибка создания файла');

 try

  // Отображаю файл в память

  HMap := CreateFileMapping(HFile, NIL, PAGE_READWRITE, 0, FSize, NIL);

  if HMap = 0 then // Исключение

  raise Exception.Create('Ошибка отображения файла');

  try

  // Создаю окно просмотра:

  AdrBase := MapViewOfFile(HMap, FILE_MAP_WRITE, 0, 0, FSize) ;

  if AdrBase = NIL then // Обработка исключения

  raise Exception.Create('Невозможно просмотреть файл');

  // Сохраняю начальный адрес для правильной ликвидации

  // Окна просмотра:

  AdrReal := AdrBase;

  for k := 1 to se.Value do

  begin

  AdrReal^ := Random; // Помещаю в файл новое число

  // Перевод текущего адреса к типу Integer перед наращиванием:

  AdrReal := Pointer(Integer(AdrReal) + SizeOf(Real));

  IbMem.Caption := IntToStr(k);

  pb.Position := k;

  Application.ProcessMessages;

  end;

  // Освобождаю окно просмотра:

  UnmapViewOfFile(AdrBase) finally

  // Освобождаю отображение
  CloseHandle(HMap);

  end

  finally   CloseHandle(HFile); // Закрываю файл

  end;

 // Сообщаю время счета pb.Hide;

 IbMem.Caption := TimeToStr(Time-BegTime)

end;

end.
Вложения
Тип файла: zip Мой вариант 2.zip (285.6 Кб, 7 просмотров)
artems67 вне форума Ответить с цитированием
Старый 01.12.2017, 13:04   #2
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Зачем усложнять и делать проецирование файлов? Оно по любому будет работать с жёстким диском. Достаточно динамического массива или использовать динамическую память GetMem /FreeMem.

Код:
procedure TForm1.Button1Click(Sender: TObject);
var a:array of byte;
i:Integer;
t1,t2:Integer;
s:Integer;
const CountMB=128; // число мегабайт для тестирования
begin
setlength(a,1024*1024*CountMB);
for i:=0 to Length(a)-1 do
  a[i]:=random(256);
s:=0;
t1:=GetTickCount();
for i:=0 to Length(a)-1 do
  s:=s+a[i];
t2:=GetTickCount();
Caption:=Format('Скорость чтения из ОЗУ %.3f МБайт/c',[CountMB/((t2-t1)/1000)]);
end;
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .

Последний раз редактировалось Pavia; 01.12.2017 в 13:08.
Pavia вне форума Ответить с цитированием
Старый 08.12.2017, 11:02   #3
artems67
Пользователь
 
Регистрация: 17.11.2015
Сообщений: 62
По умолчанию

Цитата:
Сообщение от Pavia Посмотреть сообщение
Зачем усложнять и делать проецирование файлов? Оно по любому будет работать с жёстким диском. Достаточно динамического массива или использовать динамическую память GetMem /FreeMem.

Код:
procedure TForm1.Button1Click(Sender: TObject);
var a:array of byte;
i:Integer;
t1,t2:Integer;
s:Integer;
const CountMB=128; // число мегабайт для тестирования
begin
setlength(a,1024*1024*CountMB);
for i:=0 to Length(a)-1 do
  a[i]:=random(256);
s:=0;
t1:=GetTickCount();
for i:=0 to Length(a)-1 do
  s:=s+a[i];
t2:=GetTickCount();
Caption:=Format('Скорость чтения из ОЗУ %.3f МБайт/c',[CountMB/((t2-t1)/1000)]);
end;
Спасибо за помощь.

Но я побеседовал с преподавателем. Он хочет, чтобы при нажатии кнопки "Тест" строился график, где ось X - размер блока данных, Мб. Ось y - скорость чтения блока данных из ОЗУ, Мб/с. Блоки данных изменяются с шагом, например, начинаем с 10 Мб. Шаг 5 Мб. Соответственно далее выделяется 15 мб и определяется скорость чтения блока данных из озу и т.д. Пример графика, прикреплю снизу. Но это я могу сделать сам.

Проблема в другом, почему скорость чтения не совпадает со скоростью по "документам" ? У меня оперативка с частотой 1333 Мгц. Скорость чтения должна быть около 10000 Мб/c. ( Скрин ниже )

Вторая проблема, если ввыделять больше 1 гига. Возникает ошибка "Out of Memory". Хотя я отслеживаю оперативку через мониторинг ОЗУ диспетчера задач и там пишет, что свободно около 5 гигов. Программа во время теста честно забирает 1 гиг свободной оперативки и возвращает его после выполнения. Так почему же не могу выделить больше 1 гига. Проблема в самой Delphi или ОС ?

Использовал ваш код. Пытался переделывать чтоб избежать этих ошибок. Вначале пытался решить проблему со скоростью чтения блоков данных из ОЗУ.

Вместо GetTickCount пытался использовать следующу конструкцию:

Код:
QueryPerformanceFrequency(Fr); //Частота процессора;
QueryPerformanceCounter(t); //Начальное значение счётчика;
Dt := t;

<Цикл чтение блоков данных из ОЗУ>

QueryPerformanceCounter(t); //Значение счётчика после выполнения считывания;
Dt := (t - Dt) / (Fr);
Label3.Caption:=Format('Скорость чтения из ОЗУ %.n МБайт/c',[CountMB/(Dt)]);
Стало хуже.

Ошибку Out of Memory пытался решить в конце уничтожением динамического массива через команду
Код:
a:=nil;
Не помогло.
Изображения
Тип файла: jpg 11671_23.1473121222.jpg (42.3 Кб, 74 просмотров)
Тип файла: png Безымянный.png (16.1 Кб, 128 просмотров)

Последний раз редактировалось artems67; 08.12.2017 в 11:04.
artems67 вне форума Ответить с цитированием
Старый 08.12.2017, 13:43   #4
Sciv
Старожил
 
Аватар для Sciv
 
Регистрация: 16.05.2012
Сообщений: 3,211
По умолчанию

Цитата:
скорость чтения не совпадает со скоростью по "документам" ? У меня оперативка с частотой 1333 Мгц. Скорость чтения должна быть около 10000 Мб/c. ( Скрин ниже )
А скоросто шины на материнской плате учитываете? "Стадо бежит со скоростью самого медленного его члена".

Цитата:
Вторая проблема, если ввыделять больше 1 гига. Возникает ошибка "Out of Memory".
Ну вот тут данные всей системы в студию
Начал решать проблему с помощью регулярных выражений. Теперь решаю две проблемы...
Sciv вне форума Ответить с цитированием
Старый 08.12.2017, 14:12   #5
artems67
Пользователь
 
Регистрация: 17.11.2015
Сообщений: 62
По умолчанию

Цитата:
Сообщение от Sciv Посмотреть сообщение
А скоросто шины на материнской плате учитываете? "Стадо бежит со скоростью самого медленного его члена".



Ну вот тут данные всей системы в студию
Скорость шины не учитываю.

У меня ноутбук Acer Aspire 5755G старенький 2011 года.

Мать и 2 плашки оперативы прекрепил снизу + быстрый отчёт с Aida. Вроде по харькам материнки до 20000 Мб/c пропускная способность. А вот реальная частота 600 Мгц смущает. В этом причина ? А то я в железе не профан.
Изображения
Тип файла: png мать.png (21.4 Кб, 67 просмотров)
Тип файла: png оператива1.png (34.1 Кб, 70 просмотров)
Тип файла: jpg оператива2.jpg (99.8 Кб, 120 просмотров)
Вложения
Тип файла: txt Report.txt (35.0 Кб, 132 просмотров)
artems67 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
ОЗУ Egor09 Windows 6 22.05.2014 20:28
Delphi. Работа с процессами - узнать количество занимаемой процессом памяти в ОЗУ и определить загрузку процессора alex111089 Помощь студентам 2 19.01.2013 21:44
Тестирование озу dimapo Помощь студентам 0 27.11.2012 15:20
ОЗУ Deadnight Свободное общение 16 10.04.2012 21:31
ОЗУ esa2esa Компьютерное железо 2 29.12.2010 20:45