Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Чёрно-белой растр. [D7, XP]


Страницы:   1 2

Б ©   (2009-12-20 00:58:00) 

Здрасти!

Появилась необходимость вывести черно-белый bmp, да по-быстрее.
Нашёл свой старых исходник, немного подравил.


Procedure XGrayBmp(var B: TBitmap);      // 24 bit.
Type
 TRGBTripleArray =  array [0..0] of TRGBTriple;
Var
 x, y: LongWord;
 Line: ^TRGBTripleArray;
begin
 For y:= 0 to B.Height - 1 do
 begin
   Line:= B.ScanLine[y];
   For x:= 0 to B.Width - 1 do
   With Line[x] do
   begin
     rgbtRed  := (rgbtRed + rgbtGreen + rgbtBlue) div 3;
     rgbtGreen:= rgbtRed;
     rgbtBlue := rgbtRed;
   end;
 end;
End;


Как бы её оптимизировать малехо?


Sapersky   (2009-12-21 13:09:00) [1]

Код, генерируемый сишным компилятором Visual Studio для очистки небольших (10-20 байт) структур на стеке

А это не debug-режим какой-нибудь, в котором на производительность никто особо внимания не обращает?
Или может включена оптимизация по размеру кода? Единственное преимущество stosd перед mov - в байтах она короче (1 vs 2-3). А по скорости (сейчас проверил) раза в 3 медленнее.


Anatoly Podgoretsky   (2009-12-21 11:52:00) [2]

> Игорь Шевченко  (21.12.2009 01:16:35)  [35]

МС маст дай.
В принципе это не важно, если это не в цикле и без префикса.


Игорь Шевченко   (2009-12-21 01:16:00) [3]

Sapersky   (21.12.09 00:40) [34]


> Я не блог читал, а это:
> http://www.wasm.ru/series.php?sid=11


Странно.
В http://www.wasm.ru/article.php?article=1010027
написано:

"Строковые инструкции без префикса повторения слишком медленны, и их следует заменить более простыми инструкциями. То же самое относится к LOOP на всех процессорах и к JECXZ на PPlain и PMMX. "

Код, генерируемый сишным компилятором Visual Studio для очистки небольших (10-20 байт) структур на стеке использует примерно такую последовательность команд:

xor eax,eax
mov dword ptr foo+0, eax
lea edi,foo+4
stosd
stosd
...

от двух до 5 раз stosd, если размер структуры не кратен 4, то добавляются stosw и/или stosb

Насколько я знаю, MS-овский компилятор генерирует довольно оптимальный по скорости код, поэтому непонятно, кто же прав :)


Sapersky   (2009-12-21 00:40:00) [4]

Я не блог читал, а это:
http://www.wasm.ru/series.php?sid=11
LEA, кстати, он хвалит:
http://www.wasm.ru/article.php?article=1010028
хотя по этой же статье видно, что информация несколько устаревшая (рассматриваются максимум P3):
"Целочисленные операции в большинстве своем быстрее, чем инструкции плавающей запятой, поэтому зачастую выгоднее использовать их для осуществления простых операций плавающей запятой. Наиболее очевидное применение - это перемещение данных."
...тогда как в FastCode, который затачивали в основном под P4, применяется прямо противоположный подход.

До Интеловских/Амдэшных мануалов руки так и не дошли, это да.


oxffff   (2009-12-21 00:16:00) [5]


> Sapersky   (20.12.09 23:46) [26]


There is an almost invisible war going on between Intel and AMD. It's the game of who is defining the new additions to the x86 instruction set. This war has been going on behind the scenes for years without being noticed by the majority IT professionals

http://www.agner.org/optimize/blog/read.php?i=25

Я не читал. И не знаю буду ли. :)


antonn   (2009-12-21 00:12:00) [6]

ну по крайней мере на моем проце код с lea быстрее почти на 20% (чем не правленный из [1])


oxffff   (2009-12-20 23:58:00) [7]


> ну и получается экономия операций, а не только места?


Операции разбиваются на микрооперации.
Поэтому с точки зрения количества тактов может быть идентично у этих вариантов.


0x00FF00   (2009-12-20 23:56:00) [8]


> Первый вариант, без коэфф. - не работает (в результате пустая
> картинка) и раза в 2 медленнее.С коэфф. - лень было собирать
> по строчкам, но по скорости наверное то же самое.

Прошу прощения =)
У себя пока не тестировал.
Вообще говоря, я и сам планирую написать для проекта подобную функцию, поэтому в скором времени возьмусь за это серьёзно.

Но то, что умножение оказалось медленным — обескуражило.
В FastCode'овских функциях частенько используется схожий трюк.
Видимо, напутал где-то с выравниванием...


oxffff   (2009-12-20 23:55:00) [9]


> Агнер Фог ещё пишет, что LOOP не спаривается и генерирует
> больше (по сравнению с DEC/JNZ) микроопераций.


:)
Это есть в мануале.

The following abbreviations are used in the Pairing column of the integer table in this
appendix:

NP — Not pairable, executes in U-pipe

LOOP — Loop Count   NP

Following is the table of macro-instructions and the number of μopsdecoded from each instruction.

LOOP rel8 4 μops


antonn   (2009-12-20 23:54:00) [10]


> Это используется по причине того, что занимает меньше места.
>
> Например сравните размер для

ну и получается экономия операций, а не только места?


oxffff   (2009-12-20 23:51:00) [11]


> но вместо сложения с регистром, умноженным на что-то, очень
> часто применяется инструкция LEA, если, разумеется, множитель
> попадает в диапазон, допустимый в SIB


Это используется по причине того, что занимает меньше места.
Например сравните размер для

imul eax,4;
add eax,ebx;
и

lea eax,[eax*4+ebx];


Sapersky   (2009-12-20 23:46:00) [12]

0x00FF00   (20.12.09 21:06) [12]

Первый вариант, без коэфф. - не работает (в результате пустая картинка) и раза в 2 медленнее.
С коэфф. - лень было собирать по строчкам, но по скорости наверное то же самое.

И кстати, в качестве эталонного лучше брать вариант из [10]. [11] - это я исключительно для сравнения с [1].

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

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

The LOOP instruction has a latency of at least 8 cycles.

Агнер Фог ещё пишет, что LOOP не спаривается и генерирует больше (по сравнению с DEC/JNZ) микроопераций.


Anatoly Podgoretsky   (2009-12-20 23:42:00) [13]

> Игорь Шевченко  (20.12.2009 23:34:22)  [22]

Действительно, это уже в 486 процессорах было, а на пентиумах ухудшилась. Но мои данные основаны не на книгах или на оффициальных справочниках, а на личном опыте, форумах и на измерениях.
У меня была тестовая программка, на основе LOOP -  заполнение прямоугольника 256*256 шкалой серого, когда я прочитал, что это медленная команда, я переписал на пару dec/jnz, то быстродействие возросло в несколько раз.
После этого я прочитал про сброс очереди. Латентность конечно большая, но это никак не объясняло падение скорости.


Игорь Шевченко   (2009-12-20 23:38:00) [14]

oxffff ©   (20.12.09 23:33) [21]

Вечер добрый.


> The LOOP instruction has a latency of at least 8 cycles.


У Intel в документации тоже написано, что 8 циклов для LOOP. Но там же написано, что на время задержки не всегда можно полагаться.

В общем, поверю на слово обоим.

Я к чему в ассемблер полез - периодически смотрю, какие коды генерируют разлиные компиляторы, так LOOP сейчас действительно не используется, но вместо сложения с регистром, умноженным на что-то, очень часто применяется инструкция LEA, если, разумеется, множитель попадает в диапазон, допустимый в SIB


oxffff   (2009-12-20 23:35:00) [15]

Автор найди готовую реализацию в интернете.


Игорь Шевченко   (2009-12-20 23:34:00) [16]

Anatoly Podgoretsky ©   (20.12.09 23:26) [20]

Я почему верю - у меня есть книжка R-Style "Мискропроцессор i486, архитектура и программирование", В.Л.Григорьева, там в описании команд (похоже, прямой перевод с интеловской документации), написано, что команда loop выполняется медленнее, чем dec [e]cx; jnz ...

Но не написано, почему :)


oxffff   (2009-12-20 23:33:00) [17]


> Игорь Шевченко ©   (20.12.09 22:53) [19]


Приветствую. Такое действительно имеет место быть.

40546 Software Optimization Guide for AMD Family 10h Processors
Publication # 40546 Revision: 3.00
стр. 106

6.7Avoiding the LOOP InstructionOptimization
Avoid using the LOOP instruction.Application
This optimization applies to:
•32-bit software
•64-bit software
Rationale
The LOOP instruction has a latency of at least 8 cycles.
ExampleAvoid code like this, which uses the LOOP instruction:
label: ... loop label
Instead, replace the loop instruction with a DEC and a JNZ:
label: ...
      dec rcx
      jnz label


Anatoly Podgoretsky   (2009-12-20 23:26:00) [18]

> Игорь Шевченко  (20.12.2009 22:53:19)  [19]

Информацией из групп Борланда и сообственными экспериментами десятилетней давности. Я даже не уверен, что это актуально с последними процессорами. Но с более старыми все аггрегатные функции работали медленно, что то с очередью связаное, какое то пеналти там происходит с ними.
Эксперименты проводил именно с графикой, до этого я тоже был уверен, что LOOP быстрее, оказалось на оборот.


Игорь Шевченко   (2009-12-20 22:53:00) [19]


> Команда LOOP очень медленная, пара команд dec ecx/jnz @inner_loop
> значительно быстрее.


Я конечно верю, но искал в доке Интела, не нашел, среди 70 советов по написанию кода на ассемблере ("248966_Optimization Reference Manual.pdf")

Не затруднит место указать, где можно подробнее глянуть ?


0x00FF00   (2009-12-20 22:43:00) [20]

Ах да.
Совсем заработался уже... =(
На место второго умножения нужно вставить SHR EAX, 3.

SHR EAX, 3
MUL EBX


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо