Форум программистов, компьютерный форум, киберфорум
Delphi: Графика, звук, видео
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.62/29: Рейтинг темы: голосов - 29, средняя оценка - 4.62
66 / 31 / 11
Регистрация: 18.07.2014
Сообщений: 251
1

Побитовые операции с памятью

16.03.2020, 18:01. Показов 5530. Ответов 150
Метки нет (Все метки)

Есть ли в Delphi какие-нибудь функции чтобы побитово сделать and or xor not с двумя произвольными кусками памяти? Можно чтобы это были обязательно два равных по длине куска, неважно.
Например для сравнения двух кусков есть очень быстрая функция CompareMem.
0

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

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.03.2020, 18:01
Ответы с готовыми решениями:

Побитовые операции
Задание: Дано целое неотрицательное число. Определить количество составляющих его...

Побитовые операции
С помощью побитовых операций преобразовать число -78 в 15 Вот что пыталась делать, кто знает как...

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

Побитовые операции
Выбрать алгоритм, составить его блок-схему и программу для решения выбранного варианта задания. Во...

150
2218 / 1146 / 418
Регистрация: 15.11.2015
Сообщений: 4,573
16.03.2020, 19:18 2
Над переменными операции and, or, xor делаются именно побитово.
Что конкретно нужно?
0
66 / 31 / 11
Регистрация: 18.07.2014
Сообщений: 251
16.03.2020, 19:30  [ТС] 3
AzAtom, Сделать or с большим куском памяти, например с двумя массивами байтов или просто выделенной памятью. Главное чтобы это было быстрее чем через for.
0
523 / 199 / 80
Регистрация: 11.07.2015
Сообщений: 732
16.03.2020, 21:44 4
Цитата Сообщение от KOTOM Посмотреть сообщение
есть очень быстрая функция CompareMem
Ну и
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
uses
..., SysUtils, ...
...
procedure TForm2.Button1Click(Sender: TObject);
var
  mas1, mas2: array[0..99] of Integer;
  P1, P2: Pointer;
  Len: Integer;
begin
  P1 := Addr(mas1);
  P2 := Addr(mas2);
  Len := SizeOf(mas1);
  if CompareMem(P1, P2, Len) then
    ShowMessage('Значения элементов 1-го массива идентичны значениям 2-го массива')
  else
    ShowMessage('Значения элементов 1-го массива не идентичны значениям элементов 2-го массива');
end;
0
66 / 31 / 11
Регистрация: 18.07.2014
Сообщений: 251
16.03.2020, 21:58  [ТС] 5
UR1004SWL, Ну вот мне надо не сравнить, а сделать битовую операцию. То есть вот это
Delphi
1
for i:=0 to High(mas1) do mas1[i]:=mas1[i] or mas2[i];
только быстро.

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function CompareMem(P1, P2: Pointer; Length: Integer): Boolean; assembler;
asm
        PUSH    ESI
        PUSH    EDI
        MOV     ESI,P1
        MOV     EDI,P2
        MOV     EDX,ECX
        XOR     EAX,EAX
        AND     EDX,3
        SAR     ECX,2
        JS      @@1     // Negative Length implies identity.
        REPE    CMPSD
        JNE     @@2
        MOV     ECX,EDX
        REPE    CMPSB
        JNE     @@2
@@1:    INC     EAX
@@2:    POP     EDI
        POP     ESI
end;
Как вот это переписать быстро я не понял, CMPSB и OR силшком разные команды, а с нуля на асме писать лень. Вот и спрашиваю, есть ли уже готовое?
0
пофигист широкого профиля
4412 / 2907 / 823
Регистрация: 15.07.2013
Сообщений: 16,771
16.03.2020, 22:34 6
Цитата Сообщение от KOTOM Посмотреть сообщение
То есть вот это
Delphi
Выделить код
1
for i:=0 to High(mas1) do mas1[i]:=mas1[i] or mas2[i];
только быстро.
А кто сказал что это медленно?
0
66 / 31 / 11
Регистрация: 18.07.2014
Сообщений: 251
16.03.2020, 22:41  [ТС] 7
northener, До этого я делал так сравнение, и было намного медленнее. Там у меня сравнивались две картинки попиксельно (Не через дебильный Canvas.Pixels, а я по нормальному сделал через сканлайны), и было очень медленно. Потом переписал алгоритм на CompareMem и сканлайны пихал туда, стало в 5 или 6 раз быстрее работать.
0
880 / 583 / 178
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
16.03.2020, 23:55 8
Если DIB-секции со всеми одинаковыми параметрами - можно сравнивать все пиксели одним вызовом.

Добавлено через 7 минут
а... Или чего надо-то? Всему блоку(ам) OR/XOR..?
Тогда к MMX/SSE уже...
0
66 / 31 / 11
Регистрация: 18.07.2014
Сообщений: 251
17.03.2020, 00:13  [ТС] 9
GoodWeather, Прикол в том, что я хочу сравнить БМПшку с фоном, и где фон удалён и залит фуксией. Вот хочу сделать им and по сканлайнам и так же через CompareMem сравнить.
Delphi
1
CompareMem(Pointer(DWORD(Src.ScanLine[j2])+i*3),Pointer(Sample.ScanLine[j2-j]),Sample.Width*3);
Типа так.
0
пофигист широкого профиля
4412 / 2907 / 823
Регистрация: 15.07.2013
Сообщений: 16,771
17.03.2020, 02:28 10
Цитата Сообщение от KOTOM Посмотреть сообщение
northener, До этого я делал так сравнение, и было намного медленнее. Там у меня сравнивались две картинки попиксельно (Не через дебильный Canvas.Pixels, а я по нормальному сделал через сканлайны), и было очень медленно. Потом переписал алгоритм на CompareMem и сканлайны пихал туда, стало в 5 или 6 раз быстрее работать.
Не знаю что вы когда-то и как делали. Но вот это:
Delphi
1
2
3
4
5
6
var
  mas1, mas2 : array[0..99] of Integer;
  i : Integer;
begin
  for i:=0 to High(mas1) do mas1[i]:=mas1[i] or mas2[i];
end;
вы вряд ли сможете сделать быстрее, чем это делает компилятор Дельфи
0
Миниатюры
Побитовые операции с памятью  
880 / 583 / 178
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
17.03.2020, 15:48 11
Цитата Сообщение от KOTOM Посмотреть сообщение
сканлайны
Несколько плохой термин. У вас просто "указатели на пиксели в памяти". Указатели на данные в DIB-секций.
Если форматы пикселей равны, ширина/высота/выравнивание одинаковы - можно не разбивая их по "логическим строкам" оперировать.

На MMX/SSE же быстрее. Но вручную писать фиговатто да и не красиво.
Как-то не в курсе, современные Делфи случайно не научились понимать что от них хотят SIMD?

И когда-то видел экстра-быструю версию... то ли CompareMem, то ли CopyMem... вроде от самих Intel & AMD...

Не по теме:

И кстати TCanvas изначально предполагался как просто обёртка над WinAPI:GDI32.
Так что обычный Canvas.Pixels из VCL - это просто вызов API-функций GetPixel() и SetPixel().
Которые неведомым образом до сих пор тупят по-чёрному. Все об этом знают, но чё-то никто не собирается хоть как-то фиксить...

0
Продавец времени
5782 / 3190 / 733
Регистрация: 12.03.2015
Сообщений: 15,130
17.03.2020, 16:17 12
надо бы посмотреть, во что компайлер перемелет примерно такой кот, а уже потом попытаться ещё разогнать.
Возможно, ассемблер и не понадобится.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
procedure mem_xor(var dest; const src; size: uint64);
var
  dptr: pByte absolute dest;
  sptr: pByte absolute src;
begin
  while size <> 0 do
    begin
      dptr^:= dptr^ xor sptr^;
      inc(dptr);
      inc(sptr);
      dec(size);
    end;
end;
З.Ы. Только ради эксперимента!
0
GoodWeather
17.03.2020, 16:25
  #13

Не по теме:

Ток почему по байту? Чего не PNativeUInt? Вот если Size будет не кратно - "хвост" уже придётся по байтам, да...

0
Продавец времени
5782 / 3190 / 733
Регистрация: 12.03.2015
Сообщений: 15,130
17.03.2020, 16:31 14
Цитата Сообщение от GoodWeather Посмотреть сообщение
Ток почему по байту? Чего не PNativeUInt? Вот если Size будет не кратно - "хвост" уже придётся по байтам, да...
ПАТАМУШТА!

Я ж написал:
Цитата Сообщение от Verevkin Посмотреть сообщение
З.Ы. Только ради эксперимента!
Такие вещи начинать писать надо с МАКСИМАЛЬНО ПРИМИТИВНОГО варианта. А уже потом вокруг него городить оптимизацию, свистелки и перделки.

Добавлено через 15 секунд
Цитата Сообщение от GoodWeather Посмотреть сообщение
Ток почему по байту? Чего не PNativeUInt? Вот если Size будет не кратно - "хвост" уже придётся по байтам, да...
ПАТАМУШТА!

Я ж написал:
Цитата Сообщение от Verevkin Посмотреть сообщение
З.Ы. Только ради эксперимента!
Такие вещи начинать писать надо с МАКСИМАЛЬНО ПРИМИТИВНОГО варианта. А уже потом вокруг него городить оптимизацию, свистелки и перделки.
0
2218 / 1146 / 418
Регистрация: 15.11.2015
Сообщений: 4,573
17.03.2020, 16:42 15
Ещё вариант: Берёте исходник процедуры Move и перекручиваете его на выполнение операции OR. Он там и хвост менее 4 байт учитывает тоже.

Правда, в ней SSE не пользуется. Хорошо бы использовать команду MOVNTQ, с ней запись данных ускоряется до 2-3 раз в зависимости от системы.
0
Продавец времени
5782 / 3190 / 733
Регистрация: 12.03.2015
Сообщений: 15,130
17.03.2020, 16:50 16
Начальные результаты. Судите сами:

Сам цикл (побайтный, да)
Побитовые операции с памятью


Дизассемблер:
Побитовые операции с памятью


Стоит ли дальше оптимизировать? Выкинуть 64-битный размер можно сразу.
0
Продавец времени
5782 / 3190 / 733
Регистрация: 12.03.2015
Сообщений: 15,130
17.03.2020, 16:53 17
Пойду домой, рабочий день кончился.
Проект прицеплю, вдруг кто захочет доработать напильником.
0
Вложения
Тип файла: 7z thread2599425.7z (61.6 Кб, 3 просмотров)
66 / 31 / 11
Регистрация: 18.07.2014
Сообщений: 251
17.03.2020, 17:50  [ТС] 18
Verevkin, Вот, немного переделал твой кот и на or переделал.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
procedure mem_or(Dest,Src:Pointer; Size:Int64);
var buf,i:Integer;
begin
buf:=size div 8;
for i:=0 to buf do begin
PInt64(Dest)^:=PInt64(Dest)^ or PInt64(Src)^;
Inc(DWORD(Dest),8); Inc(DWORD(Src),8); Dec(Size,8);
end;
 
buf:=Size mod 8;
for i:=0 to buf do begin
PByte(Dest)^:=PByte(Dest)^ or PByte(Src)^;
Inc(DWORD(Dest)); Inc(DWORD(Src)); Dec(Size);
end;
end;
Мне кажется while ещё медленнее чем for работает, так как он каждый раз считает условие.

Добавлено через 3 минуты
GoodWeather, На MMX/SSE у меня мозгов не хватит)
0
Продавец времени
5782 / 3190 / 733
Регистрация: 12.03.2015
Сообщений: 15,130
17.03.2020, 17:51 19
Цитата Сообщение от KOTOM Посмотреть сообщение
Мне кажется while ещё медленнее чем for работает, так как он каждый раз считает условие.
ты прав. быстрее будет
Delphi
1
for ... downto 0 do
0
66 / 31 / 11
Регистрация: 18.07.2014
Сообщений: 251
17.03.2020, 18:07  [ТС] 20
Только вот я не уверен, не будет ли глючить по 8 байт если в него пихать.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.03.2020, 18:07

Побитовые операции
Всем доброго утра. Дана такая задача: есть два чсила,поменять местами 2 последние цифры этих чисел...

Побитовые операции
От друга услышал идею о побитовой сортировки имен (например). К примеру, если у нас набор...

Побитовые операции
Задача: битовый образ 8*8 задается при помощи 8 байт, каждый байт состоит, соответственно, из 8...

Побитовые операции
Помогите решить несколько задач по битовым операциям,они все малы по реализации. И объяснить...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.