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

Вниз

Работа с битовыми масками.   Найти похожие ветки 

 
Riply ©   (2008-01-22 16:06) [0]

Здравствуйте !
Допустим, у нас есть две битовые маски.
Нам надо их сравнить и, если они различны, то выкинуть из каждой
те биты, которые есть в другой. Т.е. оставить только "отличающиеся".
У меня вот что получилось:
function DeleteEqualBits(const pBitMap1, pBitMap2: PRTL_BITMAP): DWord;
var
i: integer;
DWordCount, Tmp: DWord;
pdw1, pdw2: PULONG;
begin
Result := 0;
DWordCount := min(pBitMap1.SizeOfBitMap, pBitMap2.SizeOfBitMap) div 8;
if DWordCount > 0 then
 begin
  pdw1 := pBitMap1.Buffer;
  pdw2 := pBitMap2.Buffer;
  for i := 0 to Pred(DWordCount) do
   if pdw1^ <> pdw2^ then
    begin
     Tmp := pdw1^ xor pdw2^;
     pdw1^ := pdw1^ and Tmp;
     pdw2^ := pdw2^ and Tmp;
     inc(Result);
    end;
 end;
end;

Помогите, пожалуйста оптимизировать это безобразие,
если, конечно, оно того заслуживает :)


 
DVM ©   (2008-01-22 16:09) [1]


> Riply ©

PRTL_BITMAP у меня нет такого типа - это откуда?


 
Rouse_ ©   (2008-01-22 16:12) [2]

Тезка, а тебе не кажется что ты ксоришь только первые 4 байта масок в цикле? :)


 
homm ©   (2008-01-22 16:12) [3]

> [0] Riply ©   (22.01.08 16:06)
> Нам надо их сравнить и, если они различны, то выкинуть из
> каждой те биты, которые есть в другой.

Не понятно, что значит выкинуть? Бит может быть установлен и сброшен.


 
Семеныч   (2008-01-22 16:15) [4]

1. Делаем третью маску: Mask3 := Mask1 xor Mask2
2. Mask1 := Mask1 and Mask3; Mask2 = Mask2 and Mask3

===========

Под xor и and понимаются режимы работы BitBlt.


 
Riply ©   (2008-01-22 16:19) [5]

> [1] DVM ©   (22.01.08 16:09)

> PRTL_BITMAP у меня нет такого типа - это откуда?

RTL_BITMAP = packed record
   SizeOfBitMap: ULONG; //0  Number of bits in bit map
   Buffer: PULONG;      //4  Pointer to the bit map itself
 end;
 PRTL_BITMAP = ^RTL_BITMAP;


> [2] Rouse_ ©   (22.01.08 16:12)
> Тезка, а тебе не кажется что ты ксоришь только первые 4 байта масок в цикле? :)

:)
Вот к чему приводит спешка. Спасибо. :)
Но вопрос не отпал.


 
Rouse_ ©   (2008-01-22 16:33) [6]


> Но вопрос не отпал.

Я даже не вижу что тут можно еще оптимизировать :) Все вроде логично выстроенно...


 
Sapersky   (2008-01-22 17:04) [7]

DWordCount := min(pBitMap1.SizeOfBitMap, pBitMap2.SizeOfBitMap) div 8;

SizeOfBitMap - размер в битах или байтах?
И в том, и другом варианте в DWordCount будет явно не кол-во DWord"ов.
Ещё, если размер в байтах не обязательно кратен DWord, нужно отдельно обработать байты в конце.


 
Riply ©   (2008-01-22 17:05) [8]

> [6] Rouse_ ©   (22.01.08 16:33)
> Я даже не вижу что тут можно еще оптимизировать :) Все вроде логично выстроенно...

Тогда так и оставлю, записав ее в разряд готовых.
Правда, после исправления проверки одного и того же блока,
она стала выглядеть совсем "не эстетично" :)


 
Riply ©   (2008-01-22 17:13) [9]

> [7] Sapersky   (22.01.08 17:04)
> SizeOfBitMap - размер в битах или байтах?

В битах.

> И в том, и другом варианте в DWordCount будет явно не кол-во DWord"ов.
Точно. Спасибо.

> Ещё, если размер в байтах не обязательно кратен DWord, нужно отдельно обработать байты в конце.
Будет кратен исходя из условий инициализации (они описаны для ф-ии RtlInitializeBitMap)


 
Riply ©   (2008-01-22 17:19) [10]

Выложу ка я последний вариант, а то ошибки растут как грибы :)
Может кто еще найдет.
function DeleteEqualBits(const pBitMap1, pBitMap2: PRTL_BITMAP): DWord;
var
i: integer;
DWordCount, Tmp: DWord;
pdw1, pdw2: PULONG;
begin
Result := 0;
DWordCount := min(pBitMap1.SizeOfBitMap, pBitMap2.SizeOfBitMap) div (8 * SizeOf(DWord));
if DWordCount > 0 then
 begin
  pdw1 := pBitMap1.Buffer;
  pdw2 := pBitMap2.Buffer;
  for i := 0 to Pred(DWordCount) do
   begin
    if pdw1^ <> pdw2^ then
     begin
      Tmp := pdw1^ xor pdw2^;
      pdw1^ := pdw1^ and Tmp;
      pdw2^ := pdw2^ and Tmp;
      inc(Result);
     end
    else
     begin
      pdw1^ := 0;
      pdw2^ := 0;
     end;
    inc(pdw1);
    inc(pdw2);
   end;
 end;
end;


 
oldman ©   (2008-01-22 18:23) [11]


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


И что на выходе???


 
Sapersky   (2008-01-22 19:44) [12]

Riply ©   (22.01.08 17:19) [10]

Если уж придираться к эстетике - то const в списке параметров лишний, либо const TRTL_BITMAP, либо просто PRTL_BITMAP.
Тип DWordCount лучше сделать Integer, так же как и счётчика (i), тогда можно будет выкинуть начальную проверку на 0.


 
guav ©   (2008-01-22 23:14) [13]

А что тут делает ветвление ?
> if pdw1^ <> pdw2^ then

>    else
>     begin
>      pdw1^ := 0;
>      pdw2^ := 0;
>     end;

разве то что до else не справится с равными значениями ?


> если, конечно, оно того заслуживает :)

Что за задача ?
Я вот тоже не так давно не с того конца подошел к оптимизации, в результате выяснилось, что на самом деле проблема решается применением правильной структуры (http://delphimaster.net/view/4-1198141284/ ).


 
Riply ©   (2008-01-23 04:57) [14]

> [12] Sapersky   (22.01.08 19:44)
> Если уж придираться к эстетике - то...
"придираться к эстетике" нужно !
Спасибо. :)

> [11] oldman ©   (22.01.08 18:23)
> И что на выходе???
> [13] guav ©   (22.01.08 23:14)
> Что за задача ?

Для некого файлового объекта, двумя различными способами,
делается SnapShort дерева его "детей".
Надо сравнить результаты. (Т.е. объект такой-то есть в первом
SnapShort-е и отсутствует во втором. И наоборот.)
Если они одинаковы, то все хорошо, иначе создаем структуру,
содержащую их объеденение.
Предполагается поиск вхождений элементов одной структуры в
другую (любым способом), заменить работой с битовыми масками.
(Их можно создать на этапе сканирования, взяв за основу номер записи в MFT)
После сравнения двух масок, в них остаются только биты соответствующие
номерам записей "лишних" объектов.
Используя их легко создается наше "объеденение" SnapShort-ов.
Первые эксперименты по использованию масок впечатляют.
Они дают выигрыш по времени не в разы, а на порядки.
Плюс к этому они могут и помочь сэкономить память,
которая требуется для привеления SnapShort-ов в вид, "пригодный для сравнения" :)


 
Zeqfreed ©   (2008-01-23 07:30) [15]

Позволю себе тоже попридираться к эстетике, если позволите :)

Во-первых, в слове «снапшот» нет буквы р.
А во-вторых, DeleteEqualBits вообще никак не отображает сути функции, потому что «удалить» биты нельзя. На мой взгляд можно обозвать функцию как-нибудь наподобие SnapshotsDifference или DifferentiateSnapshots.


 
Riply ©   (2008-01-23 08:10) [16]

> [15] Zeqfreed ©   (23.01.08 07:30)
> Позволю себе тоже попридираться к эстетике, если позволите :)

Спасибо.

P.S.
Мне кажется, что в результате получится, пусть даже "не рабочая",
но зато очень эстетичная функция :)


 
guav ©   (2008-01-23 11:43) [17]

> Надо сравнить результаты. (Т.е. объект такой-то есть в первом
> SnapShort-е и отсутствует во втором. И наоборот.)
> Если они одинаковы, то все хорошо, иначе создаем структуру,
> содержащую их объеденение.

Т.е. надо просто добавлять сразу все объекты в одну сруктуру :) (разумеется, структура д.б. такова, чтобы дупликаты не добавлялись).


 
Riply ©   (2008-01-23 13:03) [18]

> [17] guav ©   (23.01.08 11:43)
> Т.е. надо просто добавлять сразу все объекты в одну сруктуру :)

Саш, думала я об этом.
Дело в том, что уж слишком велико различие между способами
сканирования и структурами с которыми они работают.
Создавать еще один вариант записи данных, пригодный и там и там ?
Получится монстр какой-то :) Ибо у каждого способа есть параметры, нужные только ему.

В первозданном виде первая "струтура" это смесь
FILE_ID_BOTH_DIR_INFORMATION и FILE_STREAM_INFORMATION,
которые заполнялись Nt - функциями с запросом на возвращение
"не единственного" вхождения и записывались в память
последовательно, по мере их поступления.
Добавлять в эту кашу (без преобразования ее в удобоворимый вид)
что-то другое не представляется возможным (или не очень просто).
Совсем другое дело - выдернуть из нее по маске
только нужные нам элементы.
Так мы избавляемся от любых ее преобразований и
поиска в ней элеменов на вхождение (что тоже не просто учитывая ее "несортированность").
Даже эта операция может понадобиться только в том случае,
если в ней окажутся элементы, не найденные вторым способом,
а это нам станет известно из сравнения масок.


 
guav ©   (2008-01-23 14:11) [19]

> [18] Riply ©   (23.01.08 13:03)

Я в подобных случаях использовал бы ассоциативные контейнеры. Дело в том, что единиц в bitmape я так понял предполагается не очень много, поэтому памяти потребуется меньше.
Даже если не хочешь смешивать массивы, сами номера я бы помещал не в bitmap а в ассоциативный контейнер.
Если нужна сортировка, то set, иначе вообще hash set.


 
guav ©   (2008-01-23 14:15) [20]

THashSet отсюда http://sourceforge.net/projects/dclx прикрутить попробуй


 
Riply ©   (2008-01-23 14:24) [21]

> [19] guav ©   (23.01.08 14:11)
> Я в подобных случаях использовал бы ассоциативные контейнеры.

А кто это такие ?

> Дело в том, что единиц в bitmape я так понял предполагается не очень много,
> поэтому памяти потребуется меньше.

Максимальное количество битов в bitmape заранее
известно: MftValidDataLength div BytesPerFileRecordSegment
(если правильно помню названия полей)


 
guav ©   (2008-01-23 14:34) [22]

> [21] Riply ©   (23.01.08 14:24)


> А кто это такие ?

Контейнеры, которые упорядочены не произвольно, а таким образом, чтобы элементы можно было находить по ключу.
У set"ов ключ и есть элемент, у map"ов элемент содержит ключ и значение. У сортированных с помощью дерева элемент ищется за логарифмическое время, и все эелементы идут в порядке, определяемом стравнением ключей. У hash контейнеров - за константное время, но элементы идут не в порядке, определяемом стравнением ключей.


> Максимальное количество битов в bitmape заранее
> известно: MftValidDataLength div BytesPerFileRecordSegment

Я понимаю. Я просто предлагаю как вариант попробовать, мож скорость не потеряешь, а память выиграешь.
Кстати, теоретически, памяти в любом случае может не хватить. для номера в MFT зарезервировано 6 байт. 2^48 div 8 больше размера 32разрядного адресного пространства 2^32.


 
Riply ©   (2008-01-23 14:47) [23]

>  [22] guav ©   (23.01.08 14:34)
> Я понимаю. Я просто предлагаю как вариант попробовать,
> мож скорость не потеряешь, а память выиграешь.

Уже скачала. Буду смотреть.

> Кстати, теоретически, памяти в любом случае может не хватить.
> для номера в MFT зарезервировано 6 байт. 2^48 div 8 больше
> размера 32разрядного адресного пространства 2^32.

Очень хочется увидеть диск, сожержащий более MAXDWORD "файловых" объектов.
Простое любопытство :)
А уж поработать на нем ! Например поискать файлы содежащие определенное слово :)


 
guav ©   (2008-01-23 15:26) [24]

Я тоже посмотрел свою ссылку, предлагаю вот что:
Раз ты всё равно исходишь из предположения, что файлов меньше MAXDWORD, использовать обычный THashSet оттуда, и приводить FILE_REFERENCE к TObject.



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

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

Наверх




Память: 0.52 MB
Время: 0.041 c
2-1201103401
smartleds
2008-01-23 18:50
2008.02.17
Народ , подскажите как мне Track Bar правильно на форме разместит


2-1201310538
BBCHa
2008-01-26 04:22
2008.02.17
Создание сервисов


2-1200993488
Skyle
2008-01-22 12:18
2008.02.17
Open Tools API и файлы не включенные в проект.


2-1200973467
Dina
2008-01-22 06:44
2008.02.17
Массив в Delphi


2-1201008769
andiv
2008-01-22 16:32
2008.02.17
изображение в MySql (blob)





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский