Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2008.07.13;
Скачать: [xml.tar.bz2];

Вниз

Warning, которого быть не должно.   Найти похожие ветки 

 
Игорь Шевченко ©   (2008-06-12 18:45) [40]


> Вдруг и здесь что-то подобное ?


а ты попробуй функцию перенести. define все те же самые, inc-файл тот же включается, функция сама не inline, посмотришь, уйдет warning или нет.


 
Riply ©   (2008-06-12 19:36) [41]

> [40] Игорь Шевченко ©   (12.06.08 18:45)
> а ты попробуй функцию перенести. define все те же самые, inc-файл тот же включается,
> функция сама не inline, посмотришь, уйдет warning или нет.

Уходит, если функция не inline

> Тын-Дын ©

> {$DEFINE SH_MEM_MNG}
> {.$DEFINE SH_MEM_DEBUG}
> {.$DEFINE SH_MEM_US_DEBUG}
> {$DEFINE SH_MEM_US_HEAP}

> program Warning;

> {$APPTYPE CONSOLE}

А разве такое "использование" директив не опасно ?
Я имею ввиду то, не получится ли что у разных юнитов разные define`ы ?

Вопрос к участникам:
Т.е. решаем пока плюнуть на этот Warning и Us_HoldInteger_ делаем не inline ?
А варнинг пусть живет как хочет :)


 
Тын-Дын ©   (2008-06-12 20:13) [42]

Я бы всё-таки убрал inline в Us_HoldInteger_, избавившись от предупреждения-)


 
Игорь Шевченко ©   (2008-06-12 21:04) [43]


> Уходит, если функция не inline


в проекте она не inline


 
Riply ©   (2008-06-12 21:10) [44]

> [43] Игорь Шевченко ©   (12.06.08 21:04)
> в проекте она не inline

Все. Я уже совсем запуталась. Не могу вспомнить в каком виде высылала проект :(
Ну да ладно. Так как решаем поступить: плюнуть (до лучших времен :) или еще помучаться ?


 
Тын-Дын ©   (2008-06-12 21:29) [45]


> в проекте она не inline


У меня в оригинале:
function Us_HoldInteger_(const pUs: PUNICODE_STRING; const Value, Base, DisplChars, SourceHoldBytes: LongWord): NTSTATUS;

implementation

function Us_HoldInteger_(const pUs: PUNICODE_STRING; const Value, Base, DisplChars, SourceHoldBytes: LongWord): NTSTATUS; {$IFNDEF SH_MEM_US_DEBUG}inline;{$ENDIF}
var
MemBlock: MEM_BLOCK;
begin
{$IFDEF SH_MEM_US_HEAP}
Result := MemBlock.__GetMemory(MAX_INT_LENGTH);
if Result = STATUS_SUCCESS then
 try
  Result := BlockMem_AppendInteger(@MemBlock, Value, Base, DisplChars);
  if NT_SUCCESS(Result) then Result := Us_HoldLen_(pUs, MemBlock.pBuffer, MemBlock.Length, SourceHoldBytes);
 finally
  MemBlock.__FreeMem;
 end;
{$ELSE}
MemBlock.InitMemBlock(SourceHoldBytes, MaximumLength, Buffer);
Result := BlockMem_AppendInteger(@MemBlock, Value, Base, DisplChars);
Us_InitFromMemBlock_(pUs, @MemBlock);
{$ENDIF}
end;


 
Riply ©   (2008-06-12 21:33) [46]

> [45] Тын-Дын ©   (12.06.08 21:29)
> У меня в оригинале:

У вас и Игорем "оригиналы" могут различаться. (Хоть убейте - не помню)
Я ведь, отправив Игорю код, не сидела сложа руки в ожидании результата :)
Могла и напартачить с исходниками :)


 
Игорь Шевченко ©   (2008-06-12 22:26) [47]

Riply ©   (12.06.08 21:10) [44]

Это я несколько ввел в заблуждение, виноват - я переместил тело функции, убрав ее прототип из интерфейсной части Sh_Unicode.
В интерфейсной части она объявлена как inline, а в implementation без него, что вполне допустимо. Так что перенеся функцию я убрал inline.


 
Игорь Шевченко ©   (2008-06-12 23:04) [48]

а эта...вопрос такой автору - а зачем такое количество вложенных друг в друга inline-функций ? Тест компилятора или иные соображения ?


 
Riply ©   (2008-06-12 23:19) [49]

> [48] Игорь Шевченко ©   (12.06.08 23:04)
> а эта...вопрос такой автору - а зачем такое количество вложенных друг в друга inline-функций ?
> Тест компилятора или иные соображения ?

Здесь все вместе.
Модуль в стадии разработки и тестирования.
На этом этапе множественность вложений позволяла почти безболезненно
менять алгоритм работы на любом "уровне" и наблюдать
за его поведением при различных условиях (в т. ч. и быстродействием).
Позже, когда было выяснено влияние inline и выбран окончательный алгоритм,
планировалось "слияние" функций и приведение модуля в рабочий, пригодный для использования вид.


 
Riply ©   (2008-06-13 00:03) [50]

Раз уж заговорили об этом, хочу поделиться.
Есть у меня код (автора, к сожалению, не помню, но не я :).
Скомпилированный под Delphi 7 и BDS 2006 он дает наглядное
представление о, изменениях в работе BMM.
Если с этим кодом чуть поиграть, то можно его использовать для
получения и других "сравнительных" данных.
Не знаю, может кому интересно будет. Ну а на "нет" и суда нет :)

unit BMM_SpeedMultiTread;

interface
uses
Windows,
SysUtils,
Classes;

procedure DiffGetMemSpeedInMultiThread(List: TStrings);

implementation
const
BorlandMM  = "borlndmm.dll";

function BMM_GetMem(Size: Integer): Pointer; external BorlandMM name "@Borlndmm@SysGetMem$qqri";
function BMM_FreeMem(P: Pointer): Integer; external BorlandMM name "@Borlndmm@SysFreeMem$qqrpv";
function _IsDebuggerPresent:boolean;external "kernel32.dll" name "IsDebuggerPresent";

//Хак - получение указателя на borlandmm.IsMultiThread
function GetBMMIsMultiThreadPtr:pBoolean;
var
 pbase,p,pp:pChar;
 pData,v:integer;
begin
 Result:=Nil;
 integer(pbase):=GetModuleHandle("borlndmm.dll");
 if pbase = Nil then Exit;
 p:=pbase+pInteger(pbase+$3C)^;     //указатель на PE-signature
 inc(p,24);                         //указатель на PE.OptionalHeader
 //начало секции данных - чтобы не возиться c анализом секций берем BaseOfData
 //(поле не обязательное для заполнения, но в borlndmm оно установлено)
 if pWord(p)^ and $100 = $100 then  //если PE32
   pData:=integer(pbase)+pInteger(p+24)^ //BaseOfData
 else
 begin                  //BaseOfCode      SizeOfCode
   pData:=integer(pbase)+pInteger(p+20)^+pInteger(p+4)^;
   pData:=(pData+4093) and -4096;
 end;
 p:=pbase+pInteger(p+16)^;              //AddressOfEntryPoint
 pp:=p+48;
 repeat
   //ищем MOV byte ptr [XXXX],1 = $05C6,$XXXX,$01
   if (pWord(p)^ = $05C6) and (pByte(p+6)^ = 1) then
   begin
     v:=pInteger(p+2)^;
     if (v >= pData) and (v < pData+$100) then
     begin
       Result:=pointer(v);
       Exit;
     end;
   end;
   inc(p);
 until p >= pp;
end;

procedure DiffGetMemSpeedInMultiThread(List: TStrings);
const
 memsz   = 8;
 repcnt  = 1;//32;
 itemcnt = 4*2;
 fmt:array[1..itemcnt] of string = (
   "GetMem+FreeMem   = %4d <- IsMultiThread:=false",
   "GetMem+FreeMem   = %4d <- IsMultiThread:=true",
   "borlandmm.dll    = %4d <- as is (dll.IsMultiThread:=true)",
   "borlandmm.dll    = %4d <- set on fly dll.IsMultiThread:=false",
   "HeapAlloc\Free   = %4d <- dwFlags = 0",
   "HeapAlloc\Free   = %4d <- dwFlags = NO_SERIALIZE",
   "GlobalAlloc\Free = %4d <- GMEM_FIXED",
   "GlobalAlloc\Free = %4d <- GMEM_MOVEABLE");
var
 t:array[0..itemcnt] of integer;
 p:array[1..3] of pointer;
 i,j,k,ph,over,heapflags:integer;
 BMMIsMultiThread:pBoolean;

 function StartRDTSC:integer;
 asm
   push ebx
   push edi
   xor eax,eax
   cpuid         //db $0F,$A2
   rdtsc         //db $0F,$31
   mov edi,eax
   xor eax,eax
   cpuid         //db $0F,$A2
   mov eax,edi
   pop edi
   pop ebx
 end;///

 function StopRDTSC:integer;
 asm
   rdtsc         //db $0F,$31
 end;///

begin
 over:=0; //замеряем оверхед на cpuid
 for j:=1 to 5 do
 begin
   t[0]:=StartRDTSC;
   t[0]:=StopRDTSC-t[0]-over;
 end;
 over:=t[0];

 IsMultiThread:=false;
 for i:=1 to 3 do GetMem(p[i],memsz);
 k:=1;
 repeat
   for j:=1 to 5 do
   begin
     t[0]:=StartRDTSC;
     for i:=1 to repcnt do
     begin
       FreeMem(p[2]);
       GetMem(p[2],memsz);
     end;
     t[k]:=(StopRDTSC-t[0]-over) div repcnt;
   end;
   IsMultiThread:=true;
   inc(k)
 until k > 2;
 IsMultiThread:=false;
 for i:=1 to 3 do FreeMem(p[i]);

 for i:=1 to 3 do p[i]:=BMM_GetMem(memsz);
 BMMIsMultiThread:=GetBMMIsMultiThreadPtr;
 repeat
   for j:=1 to 5 do
   begin
     t[0]:=StartRDTSC;
     for i:=1 to repcnt do
     begin
       BMM_FreeMem(p[2]);
       p[2]:=BMM_GetMem(memsz);
     end;
     t[k]:=(StopRDTSC-t[0]-over) div repcnt;
   end;
   if BMMIsMultiThread <> Nil then BMMIsMultiThread^:=false;
   inc(k);
 until k > 4;
 for i:=1 to 3 do BMM_FreeMem(p[i]);
 if BMMIsMultiThread <> Nil then BMMIsMultiThread^:=true;

 ph:=GetProcessHeap;
 for i:=1 to 3 do p[i]:=HeapAlloc(ph,0,memsz);
 heapflags:=0;
 repeat
   for j:=1 to 5 do
   begin
     t[0]:=StartRDTSC;
     for i:=1 to repcnt do
     begin
       HeapFree(ph,heapflags,p[2]);
       p[2]:=HeapAlloc(ph,heapflags,memsz);
     end;
     t[k]:=(StopRDTSC-t[0]-over) div repcnt;
   end;
   heapflags:=1; //=HEAP_NO_SERIALIZE;
   inc(k);
 until k > 6;
 for i:=1 to 3 do HeapFree(ph,0,p[i]);

 for i:=1 to 3 do p[i]:=pointer(GlobalAlloc(GMEM_FIXED,memsz));
 for j:=1 to 5 do
 begin
   t[0]:=StartRDTSC;
   for i:=1 to repcnt do
   begin
     GlobalFree(integer(p[2]));
     p[2]:=pointer(GlobalAlloc(GMEM_FIXED,memsz));
   end;
   t[k]:=(StopRDTSC-t[0]-over) div repcnt;
 end;
 inc(k);
 for i:=1 to 3 do GlobalFree(integer(p[i]));

 for i:=1 to 3 do p[i]:=pointer(GlobalAlloc(GMEM_MOVEABLE,memsz));
 for j:=1 to 5 do
 begin
   t[0]:=StartRDTSC;
   for i:=1 to repcnt do
   begin
     GlobalFree(integer(p[2]));
     p[2]:=pointer(GlobalAlloc(GMEM_MOVEABLE,memsz));
   end;
   t[k]:=(StopRDTSC-t[0]-over) div repcnt;
 end;
 inc(k);
 for i:=1 to 3 do GlobalFree(integer(p[i]));

 List.Add("");
 for i:=1 to k-1 do
   List.Add(Format(fmt[i],[t[i]]));
 if _IsDebuggerPresent then
   List.Add("ВНИМАНИЕ: результаты HeapAlloc\Free сильно завышены"#13#10+
                   "из-за запуска программы под отладчиком");
end;

end.


 
Игорь Шевченко ©   (2008-06-13 00:40) [51]

Riply ©   (13.06.08 00:03) [50]


> Скомпилированный под Delphi 7 и BDS 2006 он дает наглядное
>
> представление о, изменениях в работе BMM.


собственно, начиная с D2005, если я не ошибаюсь, в delphi используется FastMM вместо старого кода. Поэтому отличия они, в принципе, очевидны.

Мне больше другое интересно, а как же система работает ? Она ж тоже память выделяет под свои нужды, однако без всяких дополнительных Memory Manager"ов живет, пользуя HeapAlloc, HeapFree (они же RtlAllocateHeap, RtlFreeHeap).

И работает быстро, зараза!


 
Riply ©   (2008-06-13 01:11) [52]

> [51] Игорь Шевченко ©   (13.06.08 00:40)
> И работает быстро, зараза!

:)
Я помню как меня удивил тот факт, что Nt-функции с UNICODE_STRING работают через Heap.
А мы же их (пусть и косвенно) но вызываем "мульены" раз :)
Попробовала найти ответ на вопрос "а зачем", но кроме как у Рихтера ничего не нашла.
А он тоже выражает удивление по этому поводу.
Кстати, этот вопрос меня интересует до сих пор.
Чем я рискую, подменивая способ выделения памяти для UNICODE_STRING в Nt-функциях ?
Может это у них страховка для случая многопоточности ?


 
Игорь Шевченко ©   (2008-06-13 01:35) [53]

Riply ©   (13.06.08 01:11) [52]


> Чем я рискую, подменивая способ выделения памяти для UNICODE_STRING
> в Nt-функциях ?
> Может это у них страховка для случая многопоточности ?


Ничем. Память для буфера в Unicode_string - это самая обыкновенная память пользовательского режима и как ее выделять - это дело сугубо личное. лучше чем выделение через Heap-функции еще ничего не придумали, кроме lookaside-списков, но они для строк категорически не подходят.


> Я помню как меня удивил тот факт, что Nt-функции с UNICODE_STRING
> работают через Heap.


Собственно, практически все выделение памяти работает через Heap-функции, а они, в свою очередь работают через VirtualAlloc/VirtualFree, кроме отображения файлов на память, так что удивляться нечему.

Кстати, совет, если уж о скорости заговорили - если у тебя есть константы, которые надо передавать через UNICODE_STRING, не вызывай RtlInitUnicodeString и тем более, не выделяй под константы память и не копируй туда значения. Лучше использовать для этих целей константные строки типа
const
 MyUnicodeString: UNICODE_STRING = (Length:длина; MaximumLength:длина; Biffer:"строка");


 
Riply ©   (2008-06-13 10:29) [54]

> [53] Игорь Шевченко ©   (13.06.08 01:35)

Спасибо.



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

Форум: "Начинающим";
Текущий архив: 2008.07.13;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.58 MB
Время: 0.009 c
15-1212048925
123-ий
2008-05-29 12:15
2008.07.13
Нередактируемый документ (Web)


6-1177311252
аыпвапы
2007-04-23 10:54
2008.07.13
Клиент не отключается!!!


2-1212756942
Danco
2008-06-06 16:55
2008.07.13
Как вызвать программное нажатие клавиши в играх?


11-1189273454
Kotik666
2007-09-08 21:44
2008.07.13
Отображение HScroll в RichEdit


2-1213321722
AlexanderMS
2008-06-13 05:48
2008.07.13
Включить код на C в проект, написанный на Delphi





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский