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

Вниз

Счетчик ошибок страницы в Диспетчере задач.   Найти похожие ветки 

 
DVM ©   (2007-05-01 13:42) [0]

Что это такое? Как понимать его показания? В справке не описано.
Это нормально, когда у программы он растет со скоростью 2-3 тыс единиц в секунду?


 
homm ©   (2007-05-01 14:42) [1]

> Что это такое? Как понимать его показания?

Да не паникуй ты так. Это количество страниц, к котрым онадобился доступ когда их не было в оперативной памяти. А если еще точнее, то количество страниц, к котрым онадобился доступ когда их не было в рабочем наборе приложения, что не значит что их не было в оперативе.


> Это нормально, когда у программы он растет со скоростью
> 2-3 тыс единиц в секунду?

Нет :) Пора идти в магазин за оперативой :)


 
Eraser ©   (2007-05-01 14:42) [2]

> [0] DVM ©   (01.05.07 13:42)


> Что это такое?

это ошибка доступа к странице памяти, при её возникновении системы выгружает нужную страницу из файла подкачки в ОЗУ.

> Это нормально, когда у программы он растет со скоростью
> 2-3 тыс единиц в секунду?

не очень (хотя тут нужно смотреть конкретную ситуацию), нужно побольше ОЗУ.


 
homm ©   (2007-05-01 15:05) [3]

> Это нормально, когда у программы он растет со скоростью
> 2-3 тыс единиц в секунду?

Я счас подергал окошко оперы за края, погонял апатчь, до 5 тышь в секунду доходило. Вот же уродский оптимайзер памяти у винды :( Так что пара тысячь в секунду — вполне нормально.


 
DVM ©   (2007-05-01 15:35) [4]

Я вот попытался локализовать в своей программе место, которое более всего увеличивает счетчик - оказалось это место в FastDIB. А именно:


procedure FastDIB2Bitmap(Src:TFastDIB;Dst:TBitmap);
begin
 if Src.Handle<>0 then
 begin
   Dst.Handle:=Src.Handle;
   // bitmaps can be selected for only one device context at a time
   if(Src.hDC<>0)and Src.FreeDC then DeleteDC(Src.hDC);
   if(Src.hPen<>0)then DeleteObject(Src.hPen);
   if(Src.hFont<>0)then DeleteObject(Src.hFont);
   if(Src.hBrush<>0)then DeleteObject(Src.hBrush);
   Src.hDC:=0;
   Src.FreeDC:=False;
   Src.FreeBits:=False;
   Src.FreeHandle:=False;
 end;
end;


Вот такие преобразования моя программа делает до 200 в секунду.
Если я комментирую преобразование, то счетчик не растет практически.

Памяти 100% достаточно. Ее количество не влияет на этот счетчик. 2Гб ее.


 
Eraser ©   (2007-05-01 16:40) [5]

ну если это не дает лишней нагрузки на CPU - можно смело забить, если нагрузку дает - исключить вызов FastDIB2Bitmap.


 
antonn ©   (2007-05-01 16:43) [6]

щас может тупой вопрос задам:)
А так - procedure FastDIB2Bitmap(Src:TFastDIB; var Dst:TBitmap);
?


 
DVM ©   (2007-05-01 17:13) [7]


> ну если это не дает лишней нагрузки на CPU

Не нагрузки не дает абсолютно. Память не растет, никакие ресурсы не уменьшаются.


> щас может тупой вопрос задам:)
> А так - procedure FastDIB2Bitmap(Src:TFastDIB; var Dst:TBitmap);
>
> ?

Все то же самое.


 
Eraser ©   (2007-05-01 17:28) [8]

> [6] antonn ©   (01.05.07 16:43)

в Делфи идентификатор объекта является указателем на объект )


 
antonn ©   (2007-05-01 18:09) [9]


> в Делфи идентификатор объекта является указателем на объект
> )



 
Sapersky   (2007-05-01 20:51) [10]

Я вот попытался локализовать в своей программе место, которое более всего увеличивает счетчик - оказалось это место в FastDIB.

По логике, нужно сначала всё освободить, потом присваивать Handle. Возможно, и освобождать необязательно, во всяком случае в примере Bumpmap сделано так:

procedure TBumpForm.SetThumbnail(Image:TImage; Bmp:TFastDIB);
var
 Tmp: TFastDIB;
begin
 Tmp:=TFastDIB.Create;
 Tmp.SetSize(105,105,Bmp.Bpp);
 if Tmp.Bpp=8 then
 begin
   Tmp.Colors^:=Bmp.Colors^;
   Tmp.UpdateColors;
 end;

 Bilinear(Bmp,Tmp);
 Tmp.FreeHandle:=False;
 Image.Picture.Bitmap.Handle:=Tmp.Handle;
 Tmp.Free;
 Image.Refresh;
end;

А вообще, откуда надобность выполнять подобное преобразование 200 раз/c? Может лучше выкинуть TBitmap и выполнять все операции с TFastDIB? А то мне сейчас лень смотреть, но подозреваю, что в TBitmap.SetHandle куда больше действий, чем просто присвоение переменной.

Ещё, имейте в виду, что FastGate - это не оригинальный FastLIB. Автор этого модуля уже допускал ляпы при "улучшении" библиотеки, так что аккуратнее с ним (хотя, строго говоря, и "оригинал" не безгрешен).


 
DVM ©   (2007-05-01 22:03) [11]


> А вообще, откуда надобность выполнять подобное преобразование
> 200 раз/c?

Да есть вот задачи. Видеонаблюдение.


> Может лучше выкинуть TBitmap и выполнять все операции с
> TFastDIB?

Так и планирую сделать, но есть свои грабли и очень много вносить изменений. В принципе FastDIB тут прикручен из-за фантастически быстрой SetSize.


> TBitmap.SetHandle куда больше действий, чем просто присвоение
> переменной.

Да, там намного больше действий.


> Sapersky

Не подскажите, как правильно скопировать один TFastDIB в другой. Не Assign(), а именно копирование? У меня вот какая штука:

Во вторичном потоке происходит декодирование JPEG в TFastDIB. Далее этот FastDIB с сообщением высылается в основной поток и там преобразуется в TBitmap, который и отрисовывается при необходимости в основном потоке по WM_PAINT. Так сделано сейчас. Так вот получается, что и основной поток и вторичный на деле же работают с одним и тем же хэндлом одного и того же битмапа по сути. Ведь FastDIB2Bitmap просто присваивает хэндл. И пока первичный поток отрисовывает его на окне вторичный ведь может и поменять его содержимое. Или я неправ? Так можно делать или надо полностью копироваить битмап в основной поток и там работать с ним?


 
homm ©   (2007-05-01 22:06) [12]

Хм, а я кажеться понял почему так много ошибок доступа в этом месте. Потому что по Dst.Handle:=Src.Handle; Dst фактически заново создаеться, под новый битмап выделяеться память. А менеджер памяти в виндовсе имеет такое замечательное свойство, не выделять память физически, а лишь помечать страницы как зарезервированые. А вот когда уже на новый хэндл уже копируеться изображение со старого, идет непосредственное обращение к страницам, и они выделяются физически (в ОП), а счетчик ошибок доступа мотает. Так что эта строчка имхо — большая дыра в производительности. Попробуй как минимум создавать TBitmap как DIB, как максимум, здесь вобще нужно логику программы переделывать.


 
homm ©   (2007-05-01 22:11) [13]

> Так вот получается, что и основной поток и вторичный на
> деле же работают с одним и тем же хэндлом одного и того
> же битмапа по сути.

Скорее всего нет. Как я понимаю невозможно преобразовать DDB в DIB не выделив под него второй хэндл.


 
DVM ©   (2007-05-01 22:21) [14]


> Потому что по Dst.Handle:=Src.Handle; Dst фактически заново
> создаеться, под новый битмап выделяеться память

Да, получается, что так.


> Так что эта строчка имхо — большая дыра в производительности.

Может быть, но это далеко не самая тяжелая операция. Декодирование из JPEG во вторичных потоках занимает в тысячи раз больше времени.


> как максимум, здесь вобще нужно логику программы переделывать.

Я вот попробовал переделать на TFastDIB в основном потоке - проблема с ошибками страницы исчезла.


 
DVM ©   (2007-05-01 22:25) [15]

Возникла другая проблема - как мне правильно передать с сообщением переменную типа TFastDIB из вторичного потока в первичный с сообщением и присвоить полченное в основном потоке значение переменной в первичном потоке. Просто присваиванием очевидно нельзя - возникают сразу утечки GDI ресурсов (вот здесь отличие от TBITMAP).


 
Sapersky   (2007-05-02 00:38) [16]

Не подскажите, как правильно скопировать один TFastDIB в другой. Не Assign(), а именно копирование?

Dst.MakeCopy(Src, True); // делается SetSize и Move
Или можно (при UseGDI = True) установить размер Dst = Src, потом
Src.Draw(Dst.hDC, 0, 0); // фактически BitBlt
удобно тем, что конвертирует битмапы разных форматов, хотя, как правило, не очень качественно. Впрочем, для этого есть FConvert.pas.

И пока первичный поток отрисовывает его на окне вторичный ведь может и поменять его содержимое. Так можно делать или надо полностью копироваить битмап в основной поток и там работать с ним?

Если вторичный поток не изменяет размер битмапа, т.е. не портит указатель/Handle, то, наверное, можно его спокойно рисовать, в крайнем случае нарисуется половина старого, половина нового. Хотя сам не пробовал, не знаю, как функции GDI отнесутся к тому, что кто-то будет писать в используемую ими область памяти. Можно на всякий случай прицепить к битмапу крит. секцию.
Если изменяет - тогда однозначно нужна или синхронизация, или копирование, или и то, и другое.

Просто присваиванием очевидно нельзя - возникают сразу утечки GDI ресурсов (вот здесь отличие от TBITMAP).
Что такое "присваивание"?
Если Assign - возможно, "аффтар" FastGate с ним напортачил в новой версии, пытаясь добиться того же поведения, что и у TBitmap. В оригинале это поведение довольно специфическое - битмап-источник уничтожается.
В общем, лучше "присваивание" делать как Dst := Src с соответствующей синхронизацией или MakeCopy.


 
Игорь Шевченко ©   (2007-05-02 10:29) [17]


> Вот же уродский оптимайзер памяти у винды


Слону, сам понимаешь, пофиг.


 
DVM ©   (2007-05-02 13:00) [18]


> Sapersky   (02.05.07 00:38) [16]

Большое спасибо. Метод TFastDib.MakeCopy() действительно то что нужно.

Счетчики ошибок страницы не растут. Утечек тоже нет. Как обстоят дела с производительностью такого решения выясняю.



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

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

Наверх




Память: 0.53 MB
Время: 0.044 c
8-1158306298
megasecure
2006-09-15 11:44
2007.05.27
Графика в Delphi


2-1178504800
Konus
2007-05-07 06:26
2007.05.27
работа со string ом


1-1175153464
DelphiLexx
2007-03-29 11:31
2007.05.27
Изменить родителя при наследование


3-1173781864
Дмитрий А.
2007-03-13 13:31
2007.05.27
Как через ADO из Delphi создать столбец в таблице Access?


15-1177685246
oldman
2007-04-27 18:47
2007.05.27
Эх, жалко "Орешник" загнулся.