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

Вниз

Оптимизация кода   Найти похожие ветки 

 
Вова   (2013-07-01 16:36) [80]

и в добавок эта битовая математика ад какой то, я ничего не могу в ней понять ) откуда все понимают какие маски накладывать и все такое..


 
Sha ©   (2013-07-01 17:12) [81]

> Sapersky
> В целом, насчёт ускорения в 5-10 раз Sha всё-таки загнул.
> ещё вариант - обрабатывать пачками по 4 пикселя


как бы нам это проверить... )

> Вова
> и в добавок эта битовая математика ад какой то


если скорость нужна, научишься и разберешься: )

var
 ColorMap: array[0..16*16*16-1] of integer;
procedure ShaConvert(p: pIntegerArray; rowcount, pixelcount: integer);
var
 i, j, t, rest: integer;
begin;
 pixelcount:=pixelcount*3;
 while rowcount>0 do begin;
   rest:=pixelcount;
   while rest>=6 do begin;
     i:=p[0];
     j:=p[1];
     t:=ColorMap[i shr 24 and $F0 or j shr 4 and $F0F];
     i:=ColorMap[i and $F0 or i shr 12 and $F0F];
     p[0]:=i or t shl 24;
     if rest<12 then begin;
       pWordArray(p)[2]:=t shr 8;
       inc(pAnsiChar(p),6);
       dec(rest,6);
       break;
       end;
     i:=p[2];
     j:=ColorMap[j shr 16 and $F0 or j shr 28 and $F or i shl 4 and $F00];
     p[1]:=t shr 8 or j shl 16;
     p[2]:=j shr 16 or ColorMap[i shr 8 and $F0 or i shr 20 and $F0F] shl 8;
     inc(pAnsiChar(p),12);
     dec(rest,12);
     end;
   if rest>0 then begin; //последний нечетный пиксел
     i:=pWordArray(p)[0]+pByteArray(p)[2] shl 16;
     i:=ColorMap[i and $F0 or i shr 12 and $F0F];
     pWordArray(p)[0]:=i;
     pByteArray(p)[2]:=i shr 16;
     end;
   dec(rowcount);
   inc(pAnsiChar(p),(4-pixelcount) and 3);
   end;
 end;


 
Вова   (2013-07-01 17:22) [82]

омг, ну ради такого профита можно перейти и на 32, но вот только все эти i and $F0 это писец ) статью выше я читал, понял не очень, но это по сравнению с той статьей вообще космос )


 
Sha ©   (2013-07-01 17:24) [83]

результат давай: проценты или разы?


 
Вова   (2013-07-01 17:24) [84]

есть где нибудь описание "на пальцах" как вот это i shr 24 and $F0 or j shr 4 and $F0F понять? )


 
Sha ©   (2013-07-01 17:38) [85]

Там в коде [81] ошибочка вкралась, исправить надо:

   if rest>0 then begin; //последний нечетный пиксел
     i:=pWordArray(p)[0]+pByteArray(p)[2] shl 16;
     i:=ColorMap[i and $F0 or i shr 12 and $F0F];
     pWordArray(p)[0]:=i;
     pByteArray(p)[2]:=i shr 16;
     inc(pAnsiChar(p),3);    
     end;


 
RWolf ©   (2013-07-01 17:41) [86]


> есть где нибудь описание "на пальцах"

учебник по информатике, 7-й класс.


 
Вова   (2013-07-01 17:42) [87]


> результат давай: проценты или разы?


пока только ошибка j:=p[1];

Если p := tbmp.Scanline(tbmp.Height-1)


 
Sha ©   (2013-07-01 17:46) [88]

У меня компилится без проблем. Ты мой код меняй.
Свой меняй. И свою секретную ошибку сюда давай.


 
Sha ©   (2013-07-01 17:46) [89]

* Ты мой код не меняй.


 
Вова   (2013-07-01 17:49) [90]

я твой не менял, просто передал в функцию вот это...


 
Вова   (2013-07-01 17:50) [91]

оно компилицо, оно при выполнении вылетает с access violation


 
Sha ©   (2013-07-01 17:51) [92]

Ошибка-то какая?


 
Вова   (2013-07-01 17:54) [93]

First chance exception at $006389F5. Exception class $C0000005 with message "access violation at 0x006389f5: read of address 0x0444f000". Process SDIAPP.exe (66676)


 
Sha ©   (2013-07-01 17:54) [94]

а высоту в строках, ширину в точках передал?


 
Вова   (2013-07-01 17:59) [95]


T := GetTickCount;

p:= tbmp2.ScanLine[tbmp2.Height-1];

for I := 0 to 1000 do
   ShaConvert(p, tbmp2.Height, tbmp2.Height*tbmp2.Width);
T := GetTickCount-T;


 
Sha ©   (2013-07-01 18:00) [96]

ShaConvert(p, tbmp2.Height, tbmp2.Width);


 
Вова   (2013-07-01 18:01) [97]

хм.....да уж))


 
Вова   (2013-07-01 18:05) [98]

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


 
Sha ©   (2013-07-01 18:07) [99]

И че, ему все равно что колбасить, скорость процесса постоянна )

Ну, так все-таки разы? ))


 
Вова   (2013-07-01 18:08) [100]

вместо желтого красный, появился голубой...


 
Вова   (2013-07-01 18:10) [101]

ну по скорости да, но я как понял, 32 проще ) да и на 1 миллисекунду быстрее ))


 
Sha ©   (2013-07-01 18:12) [102]

1. правильные цвета будут только после однократного конвертирования,
конвертирование отконвертированного все ломает.

2. эта битовая математика - сущий ад, может что и не доглядел - найди и исправь )


 
Вова   (2013-07-01 18:13) [103]

и потом это все же перевернутая картинка ) после переворачивания будет те же 10 мс ) т.е. чтобы извлечь профит надо с такой же как в памяти работать.

правда у купикселей, она встает по человечески по умолчанию, так что не проверить ( кроме того купиксели работают с одинаковой скоростью и с 24 битами и с 32 (

ну я отягощен мыслью что все нужно переделывать )))


 
Sha ©   (2013-07-01 18:15) [104]

> но я как понял, 32 проще ) да и на 1 миллисекунду быстрее ))

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


 
Sha ©   (2013-07-01 18:17) [105]

> и потом это все же перевернутая картинка )
> после переворачивания будет те же 10 мс

во-первых, нафига переворачивать?

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


 
Sha ©   (2013-07-01 18:18) [106]

> купикселей, она встает по человечески по умолчанию

выпал в осадок


 
Вова   (2013-07-01 18:19) [107]

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

Переворачивать потому что у меня шаблоны то перевернутые, так что либо шаблоны переделывать, либо это переворачивать под шаблоны..


 
Sha ©   (2013-07-01 18:21) [108]

Шаблоы переворачивать один раз, картинку - постоянно.
Что выгоднее?
уууууу


 
Вова   (2013-07-01 18:24) [109]

ну вот я и говорю, что нужно переделывать, чтоб шаблоны были перевернутые.


 
Вова   (2013-07-01 18:25) [110]

вернее не перевернутые )


 
Вова   (2013-07-01 18:41) [111]

интересно, а через SetDIBits будет еще быстрее чем через сканлайн? )
может уже чтобы 2 раза потом не переделывать разобраться)


 
Sha ©   (2013-07-01 20:12) [112]

> Вова   (01.07.13 18:41) [111]

Если преобразовывать цвет в цвет, то быстрее [81,85] для 24-битного цвета не получится.
А если цвет в булеан, то можно отжать еще несколько процентов.

32-битный цвет, наверно, будет в 1.2-2.0 раза быстрее в зависимости от процессора.


 
Sapersky   (2013-07-02 07:19) [113]

Ну, так все-таки разы? ))

Разы.
Мне показалось, что было утверждение вроде "выкинь купиксели и будет тебе 5-10 раз", только за счёт выкидывания. А оказывается в [57] уже была запланирована развёртка цикла с выравниванием доступа к памяти, кто бы мог подумать :)


 
Sha ©   (2013-07-02 08:10) [114]

кто ж всю лапшу сразу вываливает на клиента, так можно отпугнуть )


 
Вова   (2013-07-02 13:25) [115]

блиииин! жил же спокойно (( раз рассказали все это теперь расскажите и что это значит

старший байт тот что в конце (слева направо)?


i := p[0]; //Берем первые 4 байта в строке (BGR + 1 байт канал B от следующего пикселя)

j := p[1]; //Берем вторые 4 байта в строке

Дальше ад:
T := ColorMap[i shr 24 and $F0 or j shr 4 and $F0F];

i shr 24 - смещение вправо 3 байт, т.е. остается канал B первого пикселя? правда он теперь на месте B второго пикселя. объединяется с `11110000` опять же не понятно как, i это же 4 байта, а не 1, или он только с последним самым правым байтом или со всеми по очереди? И главное - какой в этом смысл? Блин ну это ведь что то значит ) просто так наложили какую то лажу на канал цвета, что это с цветом то делает? ) т.е. 4 последних бита обнуляются, но нафига???

or j - первых 4 байта у которых значащими остались только первые 4 бита в последнем байте, накладываются на вторые 4 байта, получается вообще непонятно что )
j shr 4 - 4 правых бита от j удаляются. получается 4 байта с пустыми 4 битами в начале, и с какой то непонятной лажей (получившейся в результате or j) в самых правых 4 битах, а потом вообще ппц объединение с 111100001111, это ж полтора байта, как оно вообще накладывается (( на 4 байта! Обнуляются первые 4 бита правого байта? сдается мне что это не так, т.к почему тогда не 0F? ( но что за хрень это тогда?

В общем, к данному моменту кода у меня в голове полная каша не позволяющая идти дальше. Напоминает школу ) "В результате тривиальных вычислений получаем....." что получаем, откуда непонятно ( и как результат 10 впустую потраченных лет.

i := ColorMap[i and $F0 or i shr 12 and $F0F]; ну это понятно, см. выше ((

p[0] := i or T shl 24; - объединение 2х абракадабр, если у shl приоритет такой же как у or то вообще какая то херня, выкинули 3 байта остался 1 Оо

Все что я нашел об этом, это надписи о том, что в интернете куча статей об этом, видимо не такая уж и куча....Дайте ссылку хоть на одну! то что "1111000" or "00001111" = "11111111" это я вроде понял, только вот это никак не помогает понять, что в этом коде написано.


 
Вова   (2013-07-02 13:28) [116]

блин (((


 
Sha ©   (2013-07-02 13:51) [117]

1. Байты в integer нумеруются с 0 до 3. Младший байт содержит содержит младшие 8 бит, т.е. остаток от деления на 256.

2. В теории, в голове и на бумаге младший байт обычно изображают слева, старший справа, (это похоже на десятичную систему, только здесь она 256-ричная).

3. В памяти машины с архитектурой IA-32 адрес integer совпадает с адресом его младшего байта, байт номер 1 хранится по адресу на 1 больше, старший байт - по адресу на 3 больше. Можно считать, что адреса растут справа налево.  

4. Команды shr и shl имеют дело с представлением 2, причем сдвиг в действительности выполняется на указанное число бит, взятое по модулю размера операнда (т.е. 32 для integer).

5. Команды and и or с integer-операндами выполняются побитно, т.е. i and 1 вернет значение младшего бита младшего байта (1 для нечетного числа, 0 для четного), a i or 1 вернет первое нечетное после i для четного i или само i для нечетного i.


 
Sha ©   (2013-07-02 13:54) [118]

Зарапортовался, все с точностью до наоборот:

2. В теории, в голове и на бумаге младший байт обычно изображают справа, старший слева,


 
Sha ©   (2013-07-02 14:10) [119]

Допустим в переменной i лежит цвет,
интесивность каждой составляющей в своем байте (байты 0..2).
Пусть
 i:=$00aabbcc;
Каждую из них усекаем до старших 4х битов:
 i:=i and $F0F0F0;
Получаем
 i:=$00a0b0c0;
Формируем число от 0 до 16*16*16-1 - будущий индекс цвета в таблице:
 i:=(i shr 12 and $F) + (i and $F0) + (i shr 12 and $F00);
Получаем
 i:=$00000acb;
Tот же самый результат дает
 i:=i and $F0 or i shr 12 and $F0F;


 
Sha ©   (2013-07-02 14:39) [120]

Обрабатывать цвет по определению надо триплетами, читать-писать для скорости надо двойными словами.
Из-за этого небольшого противоречия возникают некоторые сложности с пониманием алгоритма )

Давай посмотрим это на простом примере. Пусть в памяти m последовательно лежат 4 байта. Надо первый из них увеличить на 1, второй умножить на 2, третий разделить на 3, четвертый оставить без изменений. Читать и писать переменную m разрешается только 1 раз.
Решение:

i:=m;
m:=(i  + 1) and $FF
  or i and $7F00 shl 1
  or i shr 16 and $FF div 3 shl 16
  or i and $FF000000;



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

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

Наверх




Память: 0.69 MB
Время: 0.019 c
2-1378324069
sas9568635
2013-09-04 23:47
2014.07.06
Вызов процедуры после выполнения таймера


15-1387524120
DevilDevil
2013-12-20 11:22
2014.07.06
Ассемблерщикам: CF/ZF


15-1387225805
Юрий
2013-12-17 00:30
2014.07.06
С днем рождения ! 17 декабря 2013 вторник


2-1378443004
shura
2013-09-06 08:50
2014.07.06
Перевести char


15-1387312202
Юрий
2013-12-18 00:30
2014.07.06
С днем рождения ! 18 декабря 2013 среда