Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Page Faults, ошибки страницы 
:(
    Опции темы
Joyer
Дата 17.1.2009, 02:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 22.1.2008

Репутация: нет
Всего: нет



Здравствуйте!
Подскажите пожалуйста что такое Page Faults или ошибки страниц?
У меня программа загружает изображения в отдельном потоке. При
этом число Page Faults увеличивается на 10,000 за каждый цикл работы потока.
Очень прошу помочь, так как вопрос срочный, а решить не получается не первые сутки.
Ниже приведена упрощенная часть кода:
Почему эти самые Page Faults увеличиваются на 2000 при попытке задать ширину битмапу?

Код

procedure TMyThread.Execute;
var
    jpeg: TJpegImage;
    Stream: TMemoryStream;
    t_bitmap: TBitmap;
begin
  t_bitmap := TBitmap.Create;
  NewBitMap:=TBitmap.Create;
  with NewBitMap do
  begin
    PixelFormat:=pf24bit;
    Width  := Screen.Width;
    Height := Screen.Height;
  end;
  jpeg := TJPEGImage.Create;
  jpeg.CompressionQuality := 100; {Default Value}
  Stream := TMemoryStream.Create;
  try
    // работаем с переменными
    // и на выходе получаем NewBitMap?
    // без синхронизации (основной поток запускает
    // рабочий и сам следит за тем, чтобы была запущена только одна его копия)
    // флаг need_to_reload_textures озн. что при рендеренге нужно обновить текстуры.

    form1.NextTexture.Assign(NewBitMap);
    need_to_reload_textures := True;

  finally
    if NewBitMap<>nil then
      NewBitMap.Free;
    if t_bitmap<>nil then
      t_bitmap.Free;
    if jpeg<>nil then
      jpeg.Free;
    if Stream<>nil then
      Stream.Free;
  end;
end;


P.S. Попытки заменить менеджер памяти на FastMM4 не увенчались успехом.
 smile 



PM MAIL   Вверх
Rrader
  Дата 17.1.2009, 10:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

Репутация: 70
Всего: 191



Не видно ни одного Synchronize, там где следовало бы smile 


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
CodeMonkey
Дата 17.1.2009, 11:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Цитата(Rrader @  17.1.2009,  10:06 Найти цитируемый пост)
Не видно ни одного Synchronize, там где следовало бы

А где следовало бы? smile))

Цитата(Joyer @  17.1.2009,  02:52 Найти цитируемый пост)
Подскажите пожалуйста что такое Page Faults или ошибки страниц?

Page faults и на русском.
Не понял, чем они вас так испугали. Работаете с большими объёмами данных - ну куда же без них?


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Rrader
  Дата 17.1.2009, 11:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

Репутация: 70
Всего: 191



Цитата(CodeMonkey @  17.1.2009,  17:00 Найти цитируемый пост)
А где следовало бы? smile  ))

smile Убейте меня


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
CodeMonkey
Дата 17.1.2009, 12:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Цитата(Rrader @  17.1.2009,  11:25 Найти цитируемый пост)
 Убейте меня 

Если NextTexture - это TBitmap, да плюс код формы не обращается к нему в промежутке, между созданием потока и need_to_reload_textures := True;, то почему-бы и нет?
Согласен, некрасиво. Но работоспособно.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Joyer
Дата 17.1.2009, 15:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 22.1.2008

Репутация: нет
Всего: нет



Спасибо огромное за ссылки и помощь в вопросе.
На одном из форумов мне подсказали, что Screen это VCL объект и без синхронизации не обойтись.
Я исправлю и перепроверю. smile 
Действительно, NextTexture это bitmap, но он используется в одном месте, для загрузки текстуры из битмапа и только при установленном  need_to_reload_textures = True.
Мне один умный человек подсказал, что в DirectX-овые текстуры желательно писать из того же потока, который инициализировал Direct 3D-шный объект.

Есть вопрос по теме: Почему возникает несколько Page Faults 
при выполнении вот этого кода

Код

  jpeg := TJPEGImage.Create;
// нет ошибки
  jpeg.CompressionQuality := 100; {Default Value}
// +8 Page Faults 



или 

Код

NewBitMap:=TBitmap.Create;
// нет ошибки
  with NewBitMap do
  begin
    PixelFormat:=pf24bit;
// +8-10 Page Faults 
    Width  := Screen.Width;
// +8-10 Page Faults 
    Height := Screen.Height;
// +8-10 Page Faults 
  end;



проверял с разными менеджерами памяти, в Delphi 7, Delphi 2007.

Причем 
NewBitMap и jpeg я объявлял как в начале процедуры, так и в объявлении объекта TMyThread - результат одинаковый.

Неужели нельзя избавиться от этих Page Faults в Delphi?
PM MAIL   Вверх
Rrader
  Дата 17.1.2009, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

Репутация: 70
Всего: 191



Цитата(Joyer @  17.1.2009,  21:21 Найти цитируемый пост)
Неужели нельзя избавиться от этих Page Faults в Delphi?

Такого рода ошибки - нормальный режим работы, и Delphi обвинять не стоит в этом. Вот пример:
Код

procedure TForm1.Button1Click(Sender: TObject);
var
  A: array[1..256000] of Integer;
begin
  A[256000] := 5;
end;

Этот пример показывает, что число ошибок страниц пропорционально объему стековой переменной, расположенной в стеке главного потока. При попытке напрямую записать память по такому дальнему смещению по логике вещей должно произойти страшное исключение - мы попадаем мимо охранной страницы (PAGE_GUARD) и будем перхвачены как нарушители доступа. Delphi таких вещей не допускает, и делает невидимую прогулку по памяти, чтобы сместить охранную страницу "пониже". Это сопровождается исключениями страниц. У меня произошло при нажатии кнопки где-то 250 исключений.

Добавлено @ 16:01
Цитата(Joyer @  17.1.2009,  21:21 Найти цитируемый пост)
На одном из форумов мне подсказали, что Screen это VCL объект и без синхронизации не обойтись.

Я поначалу тоже к этому склонялся, но затем передумал и попросил себя убить, апстенку smile Нужно знать, какие именно действия выполняет основной поток с этим Screen (я этого не знаю, но думаю, что ничего "такого" не делается). Screen глобален, это стоит учитывать. Для подстраховки можно синхронизировать...

Это сообщение отредактировал(а) Rrader - 17.1.2009, 16:39


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
CodeMonkey
Дата 17.1.2009, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Цитата(Joyer @  17.1.2009,  15:21 Найти цитируемый пост)
Неужели нельзя избавиться от этих Page Faults в Delphi?

...вы так стремитесь от них избавиться, как будто это ошибки...


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
bems
Дата 18.1.2009, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 31
Всего: 88



Цитата(Joyer @  17.1.2009,  15:21 Найти цитируемый пост)
Неужели нельзя избавиться от этих Page Faults в Delphi? 
ну если они происходят в твоем коде, то можно уменьшить их число переписав алгоритм так, чтобы адреса данных, к которым ты обращаешься лежали как можно ближе друг к другу



--------------------
Обижено школьников: 8
PM MAIL   Вверх
Joyer
Дата 19.1.2009, 04:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 22.1.2008

Репутация: нет
Всего: нет



Rrader: Спасибо огромное, крайне исчерпывающе - точный ответ на интересующий вопрос.

bems Спасибо за совет, не думаю, что у меня это получиться реализовать, но в любом случае спасибо.

Фактически, меня не волнует кол-во этих ошибок. Меня беспокоит то, что моя программа зависает.
А единственный претендент - Page faults.

Дело в том, что программа делает операции по циклу. Поток загрузил картинку, основной поток ее показал.
Так происходит около 200 раз, а потом прога виснет. Все потоки с состоянии Wait:UserRequest.
Первое о чем я подумал, - утечка памяти, но за час работы в таком режиме объем занимаемой памяти не увеличился.
Единственное, что менялось - количество Page Faults.
Вот собственно и причина моего интереса к данному вопросу.  smile
PM MAIL   Вверх
CodeMonkey
Дата 19.1.2009, 12:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Цитата(Joyer @  19.1.2009,  04:07 Найти цитируемый пост)
Фактически, меня не волнует кол-во этих ошибок. Меня беспокоит то, что моя программа зависает.А единственный претендент - Page faults.

Совершенно никак не связанные вещи. 
Попробуйте показать, как вы используете поток (похоже, Rrader может быть прав и у вас проблемы с синхронизацией).


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Joyer
Дата 20.1.2009, 05:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 22.1.2008

Репутация: нет
Всего: нет



Действительно проблемы с потоками.
Переписал все еще раз перечитав:
http://forum.vingrad.ru/forum/topic-60076.html
Петровичу Спасибо!

Вроде как стало лучше... Пока не ясно.

Код

  type
    TMyThread = class(TThread)
  Private
      FResult:      Boolean;
      FFNameToLoad: string;
      FScreenWidth:  Integer;
      FScreenHeight: Integer;
      FNewBitMap:TBitmap;
  protected
    procedure Execute; override;
  public
  //  NewBitMap: TBitMap;
    property NewBitMap: TBitMap read FNewBitMap write FNewBitMap ;
    property FNameToLoad: string read FFNameToLoad write FFNameToLoad;
    property ScreenWidth: Integer read FScreenWidth  write FScreenWidth;
    property ScreenHeight:Integer read FScreenHeight write FScreenHeight;
    property Result: Boolean read FResult write FResult;
  end;


Код

procedure TMyThread.Execute;
var
  j, new_h, new_w, new_x, new_y: integer;
  s: ansistring;
  f_ext:string;
  jpeg: TJpegImage;
  Stream: TMemoryStream;
  t_bitmap: TBitmap;
begin
  Result:=true;
  t_bitmap := TBitmap.Create;
  NewBitMap:=TBitmap.Create;
  with NewBitMap do
  begin
    PixelFormat:=pf24bit;
    Width  := ScreenWidth;
    Height := ScreenHeight;
  end;
  jpeg := TJPEGImage.Create;
  jpeg.CompressionQuality := 100;
  Stream := TMemoryStream.Create;
  try
    try
     // тут делаем страшные операции с  jpeg, NewBitMap, и Stream пока не выкладываю,
          // думаю, они не играют ключевую роль

    except
      on E: Exception do
      begin
        Result:= false;
        LogErrorThread(E.Message,'TMyThread.Execute');
      end;  
    end;
    if not Terminated then
    begin

         //Временное решение. Пока-что единственный способ, который дал мне результат. :(
             if Assigned(Form1.NextTexture) then
             Form1.NextTexture.Assign(NewBitMap);

      PostMessage(Form1.Handle, WM_THREAD_COMPLETE, 0, 0);
    end;
  finally
    if t_bitmap<>nil then
      t_bitmap.Free;
    if jpeg<>nil then
      jpeg.Free;
    if Stream<>nil then
      Stream.Free;
    if newbitmap<>nil then
      newbitmap.Free;
  end;
end;


Вот эта процедура запускается, когда рабочий поток посылает сообщение основному 
Код


procedure TForm1.HandleThreadCompletion(var Message: TMessage);
var St:TMemoryStream;
begin
  if Assigned(MyThread1) then
  begin
    MyThread1.WaitFor;
    try
не работает :(
//    form1.NextTexture.Assign(MyThread1.NewBitMap);

работает  
//   MyThread1.NewBitMap.SaveToFile('c:\x.bmp');
//   form1.NextTexture.LoadFromFile('c:\x.bmp');

      need_to_reload_textures := True;
    finally
      MyThread1.Free;
      MyThread1 := nil;
    end;
  end;
end;


Запуск потока:

Код

   if not Assigned(MyThread1)  then
     begin
        MyThread1:=TMyThread.Create(True);
        MyThread1.FreeOnTerminate:=false;
        try
          with MyThread1 do
          begin
             // NewBitMap:=nil;
             ScreenWidth:=Screen.Width;
             ScreenHeight:=Screen.Height;
             FNameToLoad := Form1.ListBox1.Items[Form1.ListBox1.ItemIndex];
             Resume;
          end;
        except
           on E: Exception do
           begin
              LogError(E.Message,'TForm1.Pict_Change');
              MyThread1.Free;
              MyThread1:=nil;
              exit;
           end;
        end;
     end;



и вот теперь есть проблема, которую не могу побороть: Я хотел считывать обработанный bitmap в  TForm1.HandleThreadCompletion.
Но, при данном коде рабочего потока - MyThread.newbitmap.free будет выполнена, и не факт, что основной поток успеет обработать сообщение. Освободить TMyThread.newbitmap в  TForm1.HandleThreadCompletion не удается.
Если ее не освобождать - происходит утечка.
Вообще "извлечь" данные TMyThread.newbitmap по окончанию TMyThread.Execute удается лишь извращенными способами вроде записи на жесткий диск или в Tmemorystream...

Подскажите пожалуйста, как поправить код, чтобы корректно присваивать Form1.NextTexture изображение полученное в MyThread1.NewBitmap...
 smile
PM MAIL   Вверх
CodeMonkey
Дата 20.1.2009, 08:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Лучше назначьте потоку событие OnTerminate:
Код
...
  MyThread1 := TMyThread.Create(True);
  try
    MyThread1.FreeOnTerminate := false;
    MyThread1.OnTerminate := ThreadTerminated;
  ...

Код
procedure TMyThread.Execute;
...
begin
  ...
  finally
    FreeAndNil(t_bitmap);
    FreeAndNil(jpeg);
    FreeAndNil(Stream);
    // <- NewBitMap оставили для внешних ссылок
  end;
end;

destructor TMyThread.Destroy; 
begin
  FreeAndNil(t_bitmap);
  FreeAndNil(jpeg);
  FreeAndNil(Stream);
  FreeAndNil(NewBitMap);
  inherited;
end;

Код
procedure TForm1.ThreadTerminate(Sender: TObject); // точную сигнатуру я не помню
begin
  if Assigned(NextTexture) then
    NextTexture.Assign(MyThread1.NewBitMap);
end;


OnTerminate вызывается в конце работы потока (сразу после выхода из Execute), причём вызывается через Synchronize в главном потоке.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Joyer
Дата 21.1.2009, 03:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 22.1.2008

Репутация: нет
Всего: нет



Я как раз и отказался от схемы, с использованием OnTerminate.
Вроде нашел ответ здесь http://www.delphikingdom.com/asp/answer.asp?IDAnswer=67842.
Еще раз все проверю - если вопрос решен ветку можно закрывать smile
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1612 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.