Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.06.2021, 20:07   #11
Viktor61
Пользователь
 
Регистрация: 05.05.2018
Сообщений: 92
По умолчанию

Ув. Kronos913! Мне очень импонирует Ваше стремление овладевать новыми знаниями (в данном случае ASM). Однако, рискну высказать своё, сугубо личное и, вероятно, ошибочное, суждение.
В настоящее время в программировании превалирует тенденция к универсализации кода (насколько это возможно): попытки сделать код, который с помощью различных ухищрений сможет работать и в Windows, и в MacOs, и на линуксе. Ассемблерные вставки полностью исключают такую возможность, т.к. даже в Windows на машинах с разной архитектурой, скажем так - ассемблерный код не всегда будут вести себя адекватно. Стоит ли изучение ASM затраченного времени?
Viktor61 вне форума Ответить с цитированием
Старый 27.06.2021, 20:28   #12
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

northener
Цитата:
Вы путаете ассемблер с волшебной палочкой.
Человек уже решил что будет изучать ассемблер нет смысла его отговаривать.

Kronos913
Никакого не слушай те делайте. К примеру Graphica32 быстрая потому что написана на ассемблере.

Что касается быстрого поворота на 90°. То секрет в блочном алгоритме изображение разбиваем на блоки по 8х8 байт. Загоням в регистры xmm. Внутри блока поворот без использования указателей или индексов, а чисто сдвигами и командами уакеовки. Плюс кэш процессора работает более оптимально.

А блоки разворачиваем при помощи индексов i,j. Загнать их в регистры esi,edi так что снизим частоту обращения к памяти.

Цитата:
Сообщение от Kronos913 Посмотреть сообщение
По идее, через ассемблер, можно как-то напрямую обращаться к каждому пикселю, без указателей?
Мечтать невредно. Вместо указателей у вас будет индека адресация и базовый регистр.

Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 28.06.2021, 00:59   #13
northener
ПШП
Участник клуба
 
Регистрация: 15.07.2013
Сообщений: 1,869
По умолчанию

Цитата:
Сообщение от Pavia Посмотреть сообщение
Человек уже решил что будет изучать ассемблер нет смысла его отговаривать.
А я и не отговариваю. Пусть изучает. Если освоит, может и что-то получится. Вот только пока у него не совсем правильное понимание программирования на ассемблере и программирования в целом. И тут процитирую уже вас
Цитата:
Сообщение от Pavia Посмотреть сообщение
То секрет в блочном алгоритме
Т.е. главное это умение составить наилучший алгоритм.
northener вне форума Ответить с цитированием
Старый 28.06.2021, 01:31   #14
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,289
По умолчанию

Цитата:
Сообщение от Kronos913 Посмотреть сообщение
Вот пример кода
Код:
procedure RotateBitmap180(SourceBitmap: TBitmap;
  out DestBitmap: TBitmap);
type
  PixelArray = array[0..32767] of TRGBTriple;
  pPixelArray = ^PixelArray;
var
  h, w, i, j: integer;
  OriginalRow, RotatedRow: pPixelArray;
  RotatedOffset, OriginalOffset: Integer;
begin
  DestBitmap.PixelFormat := pf24bit;

  h := SourceBitmap.Height - 1;
  w := SourceBitmap.Width - 1;
  DestBitmap.Height := h + 1;
  DestBitmap.Width := w + 1;

  RotatedRow := DestBitmap.Scanline[0];
  RotatedOffset := Integer(DestBitmap.ScanLine[1]) - Integer(RotatedRow);
  OriginalRow := SourceBitmap.Scanline[h];
  OriginalOffset := Integer(SourceBitmap.ScanLine[h - 1]) - Integer(OriginalRow);

  for j := 0 to h do
  begin
    for i := 0 to w do
      RotatedRow[i] := OriginalRow[w - i];
    RotatedRow := pPixelArray(Integer(RotatedRow) + RotatedOffset);
    OriginalRow := pPixelArray(Integer(OriginalRow) + OriginalOffset);
  end;
end;
Вроде в 2 раза быстрее отрабатывает (по крайней мере на моем ПК и тестовой картинке).
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 28.06.2021 в 01:35.
BDA вне форума Ответить с цитированием
Старый 28.06.2021, 07:55   #15
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Цитата:
Сообщение от northener Посмотреть сообщение
Т.е. главное это умение составить наилучший алгоритм.
Да и нет. Ассемблер даёт ряд преимуществ. Это SIMD распаролеливание по данным 1 машинная инструкция выполняет работа над несколькими данными. Чем больше регистр тем больше в нем пикселей тем быстрее работает код. Типичный пример полупрозрачные наложение(блендинг) .
По мимо SIMD современные процессоры используют MIMD как только освободился 1 каскад в конвейре блоке умножения можно засылать следующие данные. Что дает ускорения в 2 или 4 раз.
Если мы пишим на Delphi то он использует базовый набор инструкций и не использует расширения mmx, see, avx. Это дает ускорение в разы 2,4,8,16.
А базовый набор тем плох что там команды плохо спариваются. Т.е их нельзя запустить по конвейерной схеме пока предыдущая не выдаст результат.
Сейчас в процессорах развито опережающее исполнение(спекулятивное). Оно частично решает эту проблему.

Чисто за счёт распаролеливания имеем ускорение в 32 раза
Так как на ассемблер вам доступно больше регистров чем на Delphi то можно указатели и счётчики разложить по ним более оптимально чем это делает компилятор.
Снизив обращения к памяти. Обращение к памяти это от 4 до 100 тактов.

А вот алгоретмически тоже важно. К примеру в брендинге экспоненты были заменены умножением и никто разницы и незаметил.
Или частый прием заменить умножение сложением. При обращении к массиву у вас происходит вычисление адресса. При этом используется неявое, скрытое умножение. Вот BDA так и сделал. Получил ускорение в 2 раза. Правда тут ещё эффект синергии. Ушли лишние конструкции высвободились регистры. Вот и ускорение в 2 раза.

Блочный алгоритм снижает число обращений к памяти. Когда мы пишем mov eax, data и pmov mmx1, data мы читаем в первом случае 4 байта во втором уже 8. Чем большими регистры тем меньше обращений к кэш памяти тем быстрее код. И в блочном алгоритмк обращения сосредоточены по адресам. Что даёт ускорение правда тут трудно оценить насколько. Если делать обход по диагонали то это даст ещё процентов 30% ускорения может больше.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .

Последний раз редактировалось Pavia; 28.06.2021 в 08:21.
Pavia вне форума Ответить с цитированием
Старый 29.06.2021, 03:22   #16
northener
ПШП
Участник клуба
 
Регистрация: 15.07.2013
Сообщений: 1,869
По умолчанию

Цитата:
Сообщение от Pavia Посмотреть сообщение
Да и нет. Ассемблер даёт ряд преимуществ.
Я не возражаю. Но реализовать эти преимущества может только мастер хотя бы первого уровня.
Да и то не всегда.
northener вне форума Ответить с цитированием
Старый 29.06.2021, 07:28   #17
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Цитата:
Сообщение от northener Посмотреть сообщение
Я не возражаю. Но реализовать эти преимущества может только мастер хотя бы первого уровня.
Да и то не всегда.
Достаточно знать основы ассемблера и прочитать и прорешать учебник по mmx и вы также сможете:
http://sysbin.com/files/hard/mmxbook.zip
Delphi делает не очень эффективный код, так как не использует mmx и see.

Это вот с компиляторами Си соревноваться трудно так как они умеет использовать SIMD.
Хотя примеров когда ручная оптимизации выигрывает компилятор вагон и маленькая тележка:
К примеру тут человек без подготовки справился:
https://m.habr.com/ru/post/273109/
Или кодеки ffmpeg там сплошь ассемблер.

А топы развликаются решением конкурсных задач от Zimmermann'а.
http://azspcs.com/ там ради скорости пишут на ассемблере. До сентября можно успеть выучить ассемблер и подать своё решение очередной задачи.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .

Последний раз редактировалось Pavia; 29.06.2021 в 07:35.
Pavia вне форума Ответить с цитированием
Старый 01.07.2021, 01:18   #18
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 624
По умолчанию

Код:
Unit1.pas.30: for i := 1 to 10 do
0045269C B801000000       mov eax,$00000001
Unit1.pas.31: a := i;
004526A1 8BD8             mov ebx,eax
004526A3 40               inc eax
Unit1.pas.30: for i := 1 to 10 do
004526A4 83F80B           cmp eax,$0b
004526A7 75F8             jnz -$08
А как увидеть ассемблерную версию кода?
Kronos913 вне форума Ответить с цитированием
Старый 01.07.2021, 02:46   #19
northener
ПШП
Участник клуба
 
Регистрация: 15.07.2013
Сообщений: 1,869
По умолчанию

А то что вы привели разве это что-то другое?
northener вне форума Ответить с цитированием
Старый 01.07.2021, 07:28   #20
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Надо запустить проект под отладчиком. Ставишь бряк в нужном месте Alt+F8 запускаешь код F9. Затем открываем окно с дизассемблером Ctrl+shift+C или через меню view-> debug windows -> cpu.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .

Последний раз редактировалось Pavia; 01.07.2021 в 07:39.
Pavia вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Несколько вопросов Rost93 PHP 18 19.09.2012 19:38
Несколько вопросов shrek1993 Visual C++ 3 05.08.2012 18:53
несколько вопросов по C Horus92 Общие вопросы C/C++ 2 15.11.2009 16:08
несколько вопросов fitc Общие вопросы Delphi 28 14.07.2009 21:20
Несколько Вопросов Дорст Общие вопросы Delphi 3 12.11.2007 09:18