|
68 / 33 / 11
Регистрация: 18.07.2014
Сообщений: 263
|
|
Побитовые операции с памятью16.03.2020, 18:01. Показов 12643. Ответов 150
Метки нет (Все метки)
Есть ли в Delphi какие-нибудь функции чтобы побитово сделать and or xor not с двумя произвольными кусками памяти? Можно чтобы это были обязательно два равных по длине куска, неважно.
Например для сравнения двух кусков есть очень быстрая функция CompareMem.
0
|
|
| 16.03.2020, 18:01 | |
|
Ответы с готовыми решениями:
150
Побитовые операции Побитовые операции побитовые операции |
|
68 / 33 / 11
Регистрация: 18.07.2014
Сообщений: 263
|
|
| 29.03.2020, 18:20 [ТС] | |
|
murderer, Да, последняя. Альфу заполнять у сэмпла всё таки надо. Вот, обрати внимание в ro32.bmp на зелёную полоску. Я опытным путём выяснил что если её закрасить, то находит. Почему именно так я не понял. Если бы весь левый столбец надо было красить альфой, то было бы примерно понятно почему, а так непонятно.
0
|
|
|
68 / 33 / 11
Регистрация: 18.07.2014
Сообщений: 263
|
|
| 29.03.2020, 18:22 [ТС] | |
|
Там ещё есть копия куска который я вырезал без прозрачности.
Просто я этот код поиска не только не понимаю, но ещё и отладить не могу(
0
|
|
|
4195 / 1841 / 223
Регистрация: 06.10.2010
Сообщений: 4,127
|
||||||
| 29.03.2020, 20:10 | ||||||
|
Есть подозрение, что при выборке из текстуры выбирается не тот пиксель, который нужен. Дело в том, что шейдеру для выборки нужно указывать координаты в диапазоне от 0 до 1 и я перевожу пиксельные координаты в этот диапазон при помощи деления:
Ну и ещё как вариант выбирается не точное значение пикселя, а интерполированное с учётом соседей (хотя я указал GL_NEAREST, то есть не использовать интерполяцию). В общем нужно разбираться. Как отлаживать шейдеры я тоже толком не знаю. Добавлено через 2 минуты Да если взять сэмпл с котом (на котором всё работает правильно) и обрезать его, то может перестать работать, а может и нет - зависит от получившихся размеров.
0
|
||||||
|
68 / 33 / 11
Регистрация: 18.07.2014
Сообщений: 263
|
|
| 30.03.2020, 08:27 [ТС] | |
|
x128, Спросони долго вкуривал твой алгоритм. Я так понял, ты сэмпл преобразовываешь в длинный такой массив из непрозрачных пикселей (вместе с координатами). Там надо допилить напильником немного чтобы установить альфу. Но если честно, я не понял почему оно быстро работает. Если непрозрачную картинку подсунуть, то сложность получается примерно такая не как и при сравнении по три байта.
0
|
|
|
240 / 218 / 46
Регистрация: 17.04.2010
Сообщений: 526
|
||||
| 30.03.2020, 09:12 | ||||
На самом деле там могут прилететь тормоза, специфичное содержания холста и/или семпла может заставить выполнять кучу ненужных сравнений, это будет худший случай. Для лучшего случая сравнений будет не больше количества пикселей в подложке. Худший расклад хоть и маловероятен, но не исключен.
0
|
||||
|
68 / 33 / 11
Регистрация: 18.07.2014
Сообщений: 263
|
||||||
| 30.03.2020, 09:55 [ТС] | ||||||
|
x128, Просто я примерно такой же алгоритм делал, и он по сравнению с твоим отрабатывал намного дольше даже для непрозрачных картинок. Сейчас покажу.
0
|
||||||
|
240 / 218 / 46
Регистрация: 17.04.2010
Сообщений: 526
|
||
| 30.03.2020, 12:20 | ||
|
0
|
||
|
68 / 33 / 11
Регистрация: 18.07.2014
Сообщений: 263
|
||||||
| 30.03.2020, 13:14 [ТС] | ||||||
|
x128, Ну строка целиком внутри CompareMem сравнивается вообще побайтово насколько я понял. Просто эта функция работает намного быстрее чем вот эта
0
|
||||||
|
240 / 218 / 46
Регистрация: 17.04.2010
Сообщений: 526
|
|||||||
| 30.03.2020, 14:21 | |||||||
0
|
|||||||
|
68 / 33 / 11
Регистрация: 18.07.2014
Сообщений: 263
|
||||||
| 30.03.2020, 16:09 [ТС] | ||||||
|
x128, Я кстати это видел, но прикинул что это не будет особо накладно) Ну, проверю - расскажу.
Добавлено через 1 час 41 минуту В общем на самом деле взятие сканлайна оказалось очень длительным процессом. Мне было лень сегодня думать, поэтому я просто взял и все сканлайны буферизировал в массив, и получилось намного быстрее. Так же я выяснил, что сравнивать по 4 байта через = быстрее чем три байта через CompareMem. Надеюсь на днях хватит сил всё это привести в нормальный вид, а то пока эта функция выглядит как танковый полигон.
0
|
||||||
|
|
|||||
| 30.03.2020, 20:42 | |||||
|
ого... Ну вы тут и нашаманили, пока у меня не было времени поразбираться с вопросом... %))))
Чё-то уже окончательно потерял нить происходящего. Добавлено через 7 минут Нужно избегать лишних конвертаций, лишних копирований, лишних массивов, лишних вызовов функций, попробовать раскрутку цикла на 4 или 8.
ScanLine[] - жутко дорогая операция. Вам же показали выше её устройство.Вы понимаете что именно делают Changing(), DIBNeeded() и GDIFlush()? А ведь они вообще по сути не нужны.
Добавлено через 2 минуты Кажется тут пришли профи по SSE/AVX. И кажется даже чем-то покруче. Почему вы всё ещё делаете вот так как в #111? Добавлено через 9 минут От DIB-секции требуется только:
И уж точно не в циклах.
0
|
|||||
|
4195 / 1841 / 223
Регистрация: 06.10.2010
Сообщений: 4,127
|
|||||||
| 30.03.2020, 20:45 | |||||||
В общем с шейдерами я наигрался. Вроде бы поиск заработал, но при первом запуске отрабатывает очень долго: около 300 мс, повторные запуски проходят за 10-12 мс, причём большую часть времени занимает вызов glGetNamedBufferSubData. В любом случае код от x128 работает быстрее и наверное его можно немного ускорить если: 1) Делать выход из цикла через goto 2) В массив smp записывать не x и y, а линейный индекс внутри скриншота (y*width+x) и обращаться к растру не через сканлайны, а по нормальному через динамический массив. 3) В цикле repeat заменить "Image1.Width-Image2.Width" на заранее вычисленную переменную. Кстати там интересное объявление массива:
0
|
|||||||
|
4195 / 1841 / 223
Регистрация: 06.10.2010
Сообщений: 4,127
|
|
| 31.03.2020, 08:32 | |
|
Немного оптимизировал код от x128, Как вам такое:
И это без ассемблера. А ведь этот алгоритм ложится на AVX2/AVX-512 (инструкция VGATHERDPS).
1
|
|
|
4195 / 1841 / 223
Регистрация: 06.10.2010
Сообщений: 4,127
|
|
| 31.03.2020, 08:33 | |
|
И время посчитано с учётом заполнения массива smp.
0
|
|
|
68 / 33 / 11
Регистрация: 18.07.2014
Сообщений: 263
|
||||||
| 31.03.2020, 13:02 [ТС] | ||||||
|
murderer, Я просто вчера спать хотел, но захотелось быстро протестировать насколько медленный Scanline[i], вот как раз сейчас мотивируюсь переписать по нормальному. Хочу как раз попробоваить через один указатель расчитывать, ну как ты говорил через ScanLine[Height-1] и там дальше арифметикой. Придётся сравнивать снизу вверх насколько я понял, но это неважно. А ещё хочу переписать код от x128, в более юзательный вид. Там очень интересный алгоритм который я не до конца понимаю. И кстати да, array[word] тоже впервые увидел) Я до этого юзал только array[0..0] of что-тотам.
Добавлено через 35 минут GoodWeather,
0
|
||||||
|
|
|||
| 31.03.2020, 14:56 | |||
|
То есть в BMP любая строка занимает объём кратно 4 байтам, а так как один пиксель при 32-битах и есть 4 байта, то все строки лежат плотно независимо от разрешения картинки по ширине. Ну и выделять память (GetMem) на каждый пиксель, та ещё оптимизация... а если ещё захотите распараллелить на несколько потоков то потоки будут блокировать друг друга на вызове GetMem, так как выделение памяти не параллелится
0
|
|||
|
68 / 33 / 11
Регистрация: 18.07.2014
Сообщений: 263
|
||||||
| 31.03.2020, 16:43 [ТС] | ||||||
|
snake32, Насчёт трёх байт я имел ввиду, что в 24 битном битмапе один пиксель занимает три байта. Поэтому чем сравнивать трёхбайтные пиксели (а это только через CompareMem делать, а он работает побайтово), быстрее будет конвертнуть в 32 бита и сравнивать просто через <> по 4 байта сразу.
Добавлено через 52 секунды Я впринципе уже переписал этот страх и ужас, сейчас сижу придумываю как быть с x,dx,y,dy пока только по всему изображению работает. Добавлено через 1 час 26 минут В общем вот так у меня получилось. Всё что мог оптимизировал и буферизировал. Выглядит конечно так себе.
Но у меня по жизни небольшие проблемы с координатами. Я проверил вроде всё, в том числе углы. Вроде работает, нигде не вылетает в не ту память.
0
|
||||||
|
|
||
| 31.03.2020, 16:56 | ||
|
Что значит по 3 байта? У 24-хбитных битмапов блоки идут строго друг за другом, без пропусков.
Если оба битмапа 24-хбитные - сравнивать можно так же хоть по 4 хоть по 8, хоть по 16 байт, проблема только что придётся "хвост" отдельно контролировать. А вот каждый раз проверять и упаси вдруг если ещё и конвертировать PixelFormat - это очень накладно. Вы проверяли сколько это длится? Оно же весь массив копирует со сдвигами/перестановками байт. Об формате надо заботиться заранее. Менять Width/Height/PixelFormat надо как можно реже. Битмапы вы сами создаёте, или они откуда-то приходят? Не по теме: Кстати, выравнивание обязательно только в BMP-файле на диске. В памяти это уже опционально. Но при загрузке из файла выравнивание проще оставить как есть, возможно только поэтому оно почти всегда присутствует. Добавлено через 3 минуты Зачем вам вообще PSrc,PSample:Pointer;?Зачем вы выделяете под них память и заполняете через очень тормознутый ScanLine[] при каждом вызове FindInRegion()?Даже если использовать массивы указателей (кстати, по-науке то что вы сделали называется row_ptr_cache) то это надо делать только один раз после изменений свойств Width/Height/PixelFormat, а не постоянно.Добавлено через 6 минут Узнать указатель Scan0 можно через WinAPI или через TBitmap.ScanLine[0].Узнать Strde можно одновременно через тот же WinAPI или вычитанием Scan0 и TBitmap.ScanLine[1].Вот со знаком Strde может быть проблемка, WinAPI его что-то не даёт, возможно методом TBitmap безопаснее.Добавлено через 2 минуты TBitmap это уже указатель, зачем вы указатель передаёте как Var?
0
|
||
|
68 / 33 / 11
Регистрация: 18.07.2014
Сообщений: 263
|
|
| 31.03.2020, 17:08 [ТС] | |
|
GoodWeather, Src приходить будет со скриншота текущего экрана. Sample грузиться с диска (Его можно сразу сделать 32битным, тогда конвертироваться не будет, просто сравнит что он уже 32 битный). Чтобы сравнить попиксельно (у 24 битных битмапов пиксель 3 байта) нудно использовать CompareMem, а он сравнивает по 1 байту в цикле. А вот у 32 битного битмапа пиксель 4 байта, и можно сравнивать просто два DWORD.
Под PSrc и PSample память не выделяется. Это указатели на последний сканлайн битмапа. Ещё лучше их не получить. Вообще как бы подразумевается что FindInRegion не будет вызываться слишком часто. Добавлено через 1 минуту var по привычке использую. Битмап внутри может меняться. Добавлено через 20 секунд var по привычке использую. Битмап внутри может меняться. Добавлено через 1 минуту Так как битмап хранится снизу вверх я использую TBitmap.ScanLine[TBitmap.Height-1],а не TBitmap.ScanLine[0]. Добавлено через 7 минут murderer, Скинь пожалуйста свой модифицированный код. Я ту функцию чисто из-за спортивного интереса добивал) Твоя быстрее будет.
0
|
|
| 31.03.2020, 17:08 | |
|
Побитовые операции Побитовые операции Побитовые операции Побитовые операции
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства.
Жизнь действительно предъявляет каждому. . .
|
Когда логика программы не спасает от человеческих ошибок
Maks 18.08.2026
В последнее время всё чаще и чаще сталкиваюсь с таким явлением, как абсолютная невнимательность (или глупость) пользователей. Проявляется это чаще всего на работе в коллективе. Допустим, человек с. . .
|
Лето уходит
kumehtar 17.08.2026
|
Мысли в слух
kumehtar 17.08.2026
Забавно, насколько сейчас стала доступна информация. Например о магии, духовном развитии, медитациях, и других подобных направлениях, ранее зачастую тайных, передаваемых от учителя к ученику. Хотя. . .
|
|
Перемещение строк из ТЧ в другой документ с учетом текущего пробега
Maks 17.08.2026
Реализация из решения ниже выполнена на примере нетипового документа "Автозапчасти", с ТЧ "Шины".
За основу взят алгоритм отсюда: https:/ / www. cyberforum. ru/ blogs/ 359708/ 10838. html
Задача: . . .
|
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
|
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет:
1. Использовать системное время и дату,
2. Есть возможность вводить время и дату вручную.
3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
|
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber.
Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
|