Цифровой нелинейный монтаж. Комментарий к Части 5

В своей статье о Цифровом нелинейном монтаже в Части 5, автор материала Александр Чемерис сказал следующее:

Автору удалось убедится в этом при работе на ЦП iP-150 и AMD K6-200. Так, несмотря на то, что практически все тесты показывали практически 1,5-2 превосходство АМD, реально ЦП от Intel при просчете в Premiere 4.2 (без ММХ инструкций) работал на 5%-10% быстрее AMD.

Очень неплохо показали себя процессоры iPPro. Так РС с Ppro-200 256 Кбайт КЭШ при работе с Premiere 4.2 (c ММХ!) практически не уступал, а иногда и превосходил P-II 300. Правда надо заметить, что использовалась NT 4.0, для которой оптимизирован PPro. Жаль, что Intel отказалась от дальнейшего развития этой линии, мне кажется что PPro 450 под NT не оставил бы шансов Xeon'у.

Хочу прокомментировать эти два абзаца. Тем более, что, как мне кажется, это будет небезинтересно всем.

Все правильно по цифрам, наверное. По существу же объяснений у меня есть возражения:

1. AMD во времена к6 — 200 сильно уступала INTEL по скорости вычислений с плавающей запятой. Поэтому и результат измерений не в его пользу. Синтетические тесты обычно либо вообще роль FPU сводят к нулю (статистический вес вычислений с плавающей запятой в типичном наборе приложений по ZDNET невелик), либо если измеряют, то взвесь всех команд FPU разом, даже весьма экзотических. В нелинейном монтаже используется в основном float и возможно с другими стат весами, чем принято в zdnet.

2. Нам всегда говорили, что PII — это PPRO с MMX, но с кэшем, работающим на половинной частоте процессора. И еще там «починили» оптимизацию под NT. Все знают, что Интел «забыл» сделать быстрой одну команду PPRO, от чего он тормозил на 16 битном коде Windows 95. Вот такая была оптимизация под NT.

Как можно объяснить замедление PII по сравнению с PPRO — скорость общения с памятью у них для варианта PPRO200 — PII300 примерно одинаковая.

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

Время от времени я использовал свой рабочий PPRO200 для производства видео (короткие ролики-поздравления со всякими событиями).

Так вот — неправда, что PPRO лучше PII. Если нет ММХ, они одинаковы совершенно. При одинаковых тактовых частотах. Разница может быть обусловлена чем-то еще. Особенно под NT и особенно из-за дисковой подсистемы.

Как мне помнится, у NT проблемы были с bus mastering для IDE дисков. А тогда при большой скорости перезаписи видео при рендеринге процессор только диском и занят. Для SCSI все будет лучше. Хотя мой рабочий UW SCSI IBM 4.3 G и не был гигантом производительности, но процессорное время не ел.

И все равно PII 300+NT+IDE busmastering UDMA на соседнем компьютере был быстрее. Меня это интересовало чисто по причине природной склонности к экспериментам, потому и данными располагаю.

ММХ. Adobe утверждает, что ускорение от ММХ составляет от 300% до 1%, в зависимости от типа эффекта. На задачах типа компрессии Xing MPEG ускорение от ММХ примерно трехкратное или даже больше. Еще один случай, когда от ММХ есть толк, это Indeo 5.0x. Выигрыш даже на P250 MMX (3x83) по сравнению с PPRO не менее двух раз.

Частота шины памяти. У меня дома до перемены на Celeron 464 был PII 266 c коэффициентами умножения от 1.5 до 4.5. В вариантах 310=124×2.5 , 333=83×4 , 338=75×4.5, 336=112×3 , 300=66×4.5, 300=75×4 время кодирования тестового фрагмента видео в МПЕГ менялось обратно пропорционально тактовой частоте процессора с отклонениями от этой зависимоси не более 1%. Частота шины памяти вообще не сказывалась на быстродействии. Все дело, как видно, в скорости счета, а не пересылки данных. Диапазон изменения условий работы памяти довольно широкий. Да, всегда ставилось CAS delay=2, кроме крайности в 124 МГц, когда это не работало. Вообще говоря, установка CAS только на тестах памяти и меняет что-либо.

КЭШ. Больше 8% разницы в скорости при компрессии MPEG от включения или выключения L2 cache не получается. И на PII, и на Celeron 300a. У вас на сайте уже писали, что в этих условиях разница между PII и Сeleron малозаметна. Так ее и нет, как и в игрушках.

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

У меня есть сильное сомнение, что код вычислений для видео эффектов уж такой длинный. Там ведь одни циклы должны быть, и параметрические зависимости считаться. Данных много, а код скорее всего очень компактный. На битовом уровне эффекты может и программируют, но такой код становится плохо переносимым между платформами и писать его придется для каждой. А это дорого, особенно если он длинный. Проще сделать все на более высоком уровне и иметь аргумент для повышения производительности систем. MMX скорее исключение из правила.

Еще про шину данных. При сравнении времени компиляции довольно сложного проекта в Visual c++ выяснилось, что для обычных пентиумов при достаточном количестве памяти и быстром диске все определяется скоростью шины памяти.

У меня получилось, что время сборки уменьшается при повышении частоты шины почти обратно пропорционально, даже если искусственно удерживать тактовую частоту процессора. И наоборот, разгон множителем частоты почти никакого выигрыша не давал. Например P100 = 66×1.5 и P200=66×3 отличались на 10 %. Какой был проект — не скажу, я в нем только ресурсы переводил на русский язык. Самой медленной была комбинация 150=50×3 а самой быстрой — 208=83×2.5. Впрочем, удивительно здесь только уж очень выраженное игнорирование множителя частоты процессора, а не сам эффект.

Кстати, у PII300 ничего подобного нет. Мало того, что он собирает проект в полтора раза быстрее PPRO200, ему и частота шины в пределах 66-100 МГц безразлична. Не это удерживает. Более подробно не смотрел.

Григорий Байцур (baitsur@parascript.com)


Комментарий 2

Ниже приводится мнение Александра Чемериса на первый комментарий.

Сначала процитирую Григория Байцура:

У меня есть сильное сомнение, что код вычислений для видео эффектов уж такой длинный. Там ведь одни циклы должны быть, и параметрические зависимости считаться. Данных много, а код, скорее всего очень компактный. На битовом уровне эффекты может, и программируют, но такой код становится плохо переносимым между платформами, и писать его придется для каждой. А это дорого, особенно если он длинный. Проще сделать все на более высоком уровне и иметь аргумент для повышения производительности систем. MMX скорее исключение из правила.

Теперь выскажу свое мнение:

Данное рассуждение справедливо для работы с простыми эффектами типа шторки. Сложные эффекты с использованием преобразования Гаусса и 3D эффекты сильно нагружают ЦП, не оптимизированный под векторные преобразования. Более того, алгоритм просчета эффектов сильно зависит от «интеллектуальности» ПО.

Простой пример. Необходимо обработать 2 эффекта на 1 кадре. Первый эффект — обработка кадра (например — поворот кадра в плоскости, псевдо 3D эффект), второй — наложение титров по ключу. Выполнить эту обработку ЦП может несколькими способами:

Первый - последовательное выполнение эффектов. Вначале ЦП (вернее алгоритм ПО) рассчитывает новые координаты точек кадра, а затем происходит просчет наложения 2-го изображения поверх первого. При этом необходимо загрузить и выполнить две последовательности команд ЦП. Если ПО достаточно «интеллектуально», то оно проанализирует возможности загрузки обоих последовательностей в КЭШ. Иначе просто будет выполнено два цикла обращения к ОЗУ.

Второй вариант. Анализируются оба изображения на область точек перекрытия. Просчитывается возможность распараллеливания вычислений. Понятно, что область закрытая вторым изображением может не просчитываться на эффект поворота, а сразу рассчитываться по алгоритму замещения точек изображения. При этом имеется возможность одновременной загрузки, как целочисленного АЛУ, так и АЛУ для чисел с плавающей точкой, при условии возможности их одновременной работы. Выигрыш в скорости очевиден. Следует заметить, что при наличии векторного ЦП с размерностью 2048×2048 векторов, расчет данного эффекта теоретически мог занять один цикл такого ЦП.

Теперь что касается переносимости кода. При всей разнообразности платформ ЦП, основной набор команд достаточно стандартный и при наличии хороших компиляторов, не составит большой проблемы. Проблемы могут возникнуть как раз при переносе кода, например, на векторные ЦП. Что касается использования более высокого уровня команд, то в принципе так оно и есть. Большое количество эффектов сторонних разработчиков используют именно этот способ для дополнения к существующему ПО. Правда такой подход ограничивает количество ПО, на котором доступны эти эффекты.

Следует заметить и еще такой фактор. Быстро растущие мощности ЦП, при снижении стоимости и необходимость удержания на рынке, заставляют разработчиков ПО идти по интенсивному пути развития.

Александр Чемерис (admin@ailant.komi.ru)


Комментарий 3

Про векторные вычисления ничего не могу сказать, таких в нашем мире PC от Интела нет.

Про обработку изображения можно добавить к сказанному в комментарии на комментарий следующее:

Давайте спустимся на землю.

Я по молодости считал подобные «эффекты», делая расчеты двумерных и трехмерных электрических полей с учетом сложной геометрии и распределения объемных зарядов в пространстве. В некотором смысле это и был сложный видео эффект. Я имел на экране одну исходную картинку (граничные условия и распределение объемного заряда —типичная задача в физике низкотемпературной плазмы), и мне надо было по алгоритму из нее сделать другую — распределение поля.

Так вот, решение в одной точке зависело от очень многих точек исходной картинки — плотности заряда, координаты, форма электродов… Типичный случай сложного эффекта в видеомонтаже. Уверяю вас, что сложность зависимости конечного результата от начальных данных не определяет длину кода. В моем случае приходилось решать все итерационно, перебирая «пикселы» и делая над ними вычисления. Размер «картинки» был от 30×30 до 1200×1200 точек. Но, весь код содержал несколько циклов по всем точкам, в цикле было до полусотни ассемблерных команд. Делалось все на Паскале 7.0 в защищенном режиме, поэтому я мог в «куче» создать такие большие псевдомассивы. На встроенный ассемблер я перешел только по причине сильной тормознутости кода на Паскале. Там вообще никакой оптимизации не делалось. Вся программа оперировала с данными до 20 МБ, а ее код был не более 40-50 КБ и исполняемый код ЦИКЛА заведомо помещался в кэш ПЕРВОГО уровня. Не надо смешивать количество вычислений (проходов цикла) с длиной кода. Это очевидно разные вещи.

Если алгоритм общения с кэшем сделан хоть немного разумно, то последовательный перебор точек одной картинки с целью просчета их координат и откладывания значений в другой массив работает эффективно и без кэша второго уровня. Делается просто пакетное чтение из основной памяти группы байт прямо в кэш первого уровня, поскольку перебор последовательный, то все работает очень быстро. Я тогда специально исследовал (3-6 лет назад) влияние кэша и его размера на скорость счета.

Размер кэша в 386 машине ничего не значил, 64 и 128 к варианты работали просто одинаково. Выключение кэша все тормозило вдвое, но это и понятно для 386 DX40.

Размер кэша второго уровня у 486 машин тоже не имел значения. Его отключение, или использование безкэшевого варианта (ноутбук 486 DX 2 50) замедляло расчеты на 5-7%. Отключение кэша первого уровня все сильно тормозило. Здесь наличие кэша второго уровня сказывалось заметно, потому что код цикла мог не вполне помещаться в кэш первого уровня из-за его малой величины.

Лирическое отступление. Забавно, но из моих тогдашних опытов проистекло следующее наблюдение: если и код и данные программки помещались в кэш первого уровня, то на ноутбуке происходило следующее. В чистом ДОСЕ, в обычном real паскале, цикл типа a:=b*c исполнялся быстро только первую минуту. Затем все тормозилось втрое. Я не мог понять, почему не могу измерить время исполнения одной команды умножения, написав цикл из миллиона умножений и повесив сверху измеряющий время пять раз подряд цикл. После первого прохода все жутко замедлялось. В защищенном режиме, или в окне ДОС под Win3.1 все работало без тормозов. Если вместо перемножения одной пары чисел я брал массив >8К (если 4к, то я не виноват, половина полного размера кэша была) и перебирал его, то эффект замедления пропадал. Граница сидела около размера кэша данных первого уровня. Так вот, оказалось, что если весь исполняемый код и данные находятся внутри кэша первого уровня, то система энергосбережения ноутбука считала,что он просто ничего полезного не делает и снижала частоту втрое.

Разницы во времени прохода цикла с большим массивом и с маленьким, умещавшимся в кэш, в одинаковых protected code условиях я вообще не заметил. Таким образом, производительность не зависела от того, уместились все последовательно перебираемые данные в кэш или нет. Все делалось, разумеется, на плавающей точке, довольно медленно работавшей на 386486 машинах.

На пентиуме, выключение кэша второго уровня уменьшало скорость на 3%. Размер этого кэша на скорость не влиял. Размер массива данных тоже. Процессор просто обрабатывал 4 байта новых данных за большее число тактов, чем это нужно для их извлечения в выровненном по границам в 4 байт и пакетном режиме.

На пентиуме про я с трудом смог свою старую программку запустить, спасибо Борланду. Все уже слышали, что паскаль их падает на машинах быстрее ППРО 180. Если процессор чем-нибудь отвлечь при загрузке кода, то удавалось программку запустить. Никаких чудес не произошло, а Пентиум2 300 был в полтора раза быстрее, как ему и положено.

Я полагаю, что оба эффекта из примера в комментарии к моей заметке работают-таки последовательно. Ведь это разные эффекты и написаны разными кусками кода. Кто-то выполняется раньше. А что, надо много кода для вычисления координаты точки при повороте? Мне казалось раньше, что четырех строк хватит. Два десятка ассемблерных команд. Потом, когда все повернется, можно запустить второй проход по «облагораживанию» типа antialiasing. Это и программировать и проще результат выходит предсказуемый. Для antialiasing опять кода надо мало, только считать много.

А вот теперь и потитровать можно.

Гауссовы преобразования тоже последовательным перебором пикселов с вычислениями делаются. Ничего особенного в этом случае тоже нет. Хотя для экстремистских случаев гауссового размытия на всю картинку и медленно все будет, но точка, из которой добавочки по всем другим разлетаются — одна, а выходные перебираются последовательно. Опять конвейер выходит, что для кэша равносильно его непризнанию. Не вижу я ни одного примера из приведенных, где бы КОД был длинный. Про данные я уже говорил, если над каждым пикселом надо потрудиться, то обмен с основной памятью не есть замедляющий фактор.

Декомпрессия. Включается сторонний алгоритм, обычно поставляющий на выход в память bitmap. Он работает медленнее, чем может память. Размер исполняемого кода алгоритма декомпрессии/компрессии небольшой. Данные обрабатываются последовательно, алгоритм вычислений сравнительно простой, но может быть трудоемким по числу операций. Длина последовательности команд в цикле почти наверняка небольшая.

Про векторные вычисления написано красиво. Но я в молодости лазеры бо-о-льшие делал и разрабатывал, не понять мне красоты…

Григорий Байцур (baitsur@parascript.com)





23 февраля 1999 Г.

Digital Nonlinear Video Assembling on PC. Part 5 Comments

Цифровой нелинейный монтаж. Комментарий к Части 5

В своей статье о Цифровом нелинейном монтаже в Части 5, автор материала Александр Чемерис сказал следующее:

Автору удалось убедится в этом при работе на ЦП iP-150 и AMD K6-200. Так, несмотря на то, что практически все тесты показывали практически 1,5-2 превосходство АМD, реально ЦП от Intel при просчете в Premiere 4.2 (без ММХ инструкций) работал на 5%-10% быстрее AMD.

Очень неплохо показали себя процессоры iPPro. Так РС с Ppro-200 256 Кбайт КЭШ при работе с Premiere 4.2 (c ММХ!) практически не уступал, а иногда и превосходил P-II 300. Правда надо заметить, что использовалась NT 4.0, для которой оптимизирован PPro. Жаль, что Intel отказалась от дальнейшего развития этой линии, мне кажется что PPro 450 под NT не оставил бы шансов Xeon'у.

Хочу прокомментировать эти два абзаца. Тем более, что, как мне кажется, это будет небезинтересно всем.

Все правильно по цифрам, наверное. По существу же объяснений у меня есть возражения:

1. AMD во времена к6 — 200 сильно уступала INTEL по скорости вычислений с плавающей запятой. Поэтому и результат измерений не в его пользу. Синтетические тесты обычно либо вообще роль FPU сводят к нулю (статистический вес вычислений с плавающей запятой в типичном наборе приложений по ZDNET невелик), либо если измеряют, то взвесь всех команд FPU разом, даже весьма экзотических. В нелинейном монтаже используется в основном float и возможно с другими стат весами, чем принято в zdnet.

2. Нам всегда говорили, что PII — это PPRO с MMX, но с кэшем, работающим на половинной частоте процессора. И еще там «починили» оптимизацию под NT. Все знают, что Интел «забыл» сделать быстрой одну команду PPRO, от чего он тормозил на 16 битном коде Windows 95. Вот такая была оптимизация под NT.

Как можно объяснить замедление PII по сравнению с PPRO — скорость общения с памятью у них для варианта PPRO200 — PII300 примерно одинаковая.

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

Время от времени я использовал свой рабочий PPRO200 для производства видео (короткие ролики-поздравления со всякими событиями).

Так вот — неправда, что PPRO лучше PII. Если нет ММХ, они одинаковы совершенно. При одинаковых тактовых частотах. Разница может быть обусловлена чем-то еще. Особенно под NT и особенно из-за дисковой подсистемы.

Как мне помнится, у NT проблемы были с bus mastering для IDE дисков. А тогда при большой скорости перезаписи видео при рендеринге процессор только диском и занят. Для SCSI все будет лучше. Хотя мой рабочий UW SCSI IBM 4.3 G и не был гигантом производительности, но процессорное время не ел.

И все равно PII 300+NT+IDE busmastering UDMA на соседнем компьютере был быстрее. Меня это интересовало чисто по причине природной склонности к экспериментам, потому и данными располагаю.

ММХ. Adobe утверждает, что ускорение от ММХ составляет от 300% до 1%, в зависимости от типа эффекта. На задачах типа компрессии Xing MPEG ускорение от ММХ примерно трехкратное или даже больше. Еще один случай, когда от ММХ есть толк, это Indeo 5.0x. Выигрыш даже на P250 MMX (3x83) по сравнению с PPRO не менее двух раз.

Частота шины памяти. У меня дома до перемены на Celeron 464 был PII 266 c коэффициентами умножения от 1.5 до 4.5. В вариантах 310=124×2.5 , 333=83×4 , 338=75×4.5, 336=112×3 , 300=66×4.5, 300=75×4 время кодирования тестового фрагмента видео в МПЕГ менялось обратно пропорционально тактовой частоте процессора с отклонениями от этой зависимоси не более 1%. Частота шины памяти вообще не сказывалась на быстродействии. Все дело, как видно, в скорости счета, а не пересылки данных. Диапазон изменения условий работы памяти довольно широкий. Да, всегда ставилось CAS delay=2, кроме крайности в 124 МГц, когда это не работало. Вообще говоря, установка CAS только на тестах памяти и меняет что-либо.

КЭШ. Больше 8% разницы в скорости при компрессии MPEG от включения или выключения L2 cache не получается. И на PII, и на Celeron 300a. У вас на сайте уже писали, что в этих условиях разница между PII и Сeleron малозаметна. Так ее и нет, как и в игрушках.

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

У меня есть сильное сомнение, что код вычислений для видео эффектов уж такой длинный. Там ведь одни циклы должны быть, и параметрические зависимости считаться. Данных много, а код скорее всего очень компактный. На битовом уровне эффекты может и программируют, но такой код становится плохо переносимым между платформами и писать его придется для каждой. А это дорого, особенно если он длинный. Проще сделать все на более высоком уровне и иметь аргумент для повышения производительности систем. MMX скорее исключение из правила.

Еще про шину данных. При сравнении времени компиляции довольно сложного проекта в Visual c++ выяснилось, что для обычных пентиумов при достаточном количестве памяти и быстром диске все определяется скоростью шины памяти.

У меня получилось, что время сборки уменьшается при повышении частоты шины почти обратно пропорционально, даже если искусственно удерживать тактовую частоту процессора. И наоборот, разгон множителем частоты почти никакого выигрыша не давал. Например P100 = 66×1.5 и P200=66×3 отличались на 10 %. Какой был проект — не скажу, я в нем только ресурсы переводил на русский язык. Самой медленной была комбинация 150=50×3 а самой быстрой — 208=83×2.5. Впрочем, удивительно здесь только уж очень выраженное игнорирование множителя частоты процессора, а не сам эффект.

Кстати, у PII300 ничего подобного нет. Мало того, что он собирает проект в полтора раза быстрее PPRO200, ему и частота шины в пределах 66-100 МГц безразлична. Не это удерживает. Более подробно не смотрел.

Григорий Байцур (baitsur@parascript.com)


Комментарий 2

Ниже приводится мнение Александра Чемериса на первый комментарий.

Сначала процитирую Григория Байцура:

У меня есть сильное сомнение, что код вычислений для видео эффектов уж такой длинный. Там ведь одни циклы должны быть, и параметрические зависимости считаться. Данных много, а код, скорее всего очень компактный. На битовом уровне эффекты может, и программируют, но такой код становится плохо переносимым между платформами, и писать его придется для каждой. А это дорого, особенно если он длинный. Проще сделать все на более высоком уровне и иметь аргумент для повышения производительности систем. MMX скорее исключение из правила.

Теперь выскажу свое мнение:

Данное рассуждение справедливо для работы с простыми эффектами типа шторки. Сложные эффекты с использованием преобразования Гаусса и 3D эффекты сильно нагружают ЦП, не оптимизированный под векторные преобразования. Более того, алгоритм просчета эффектов сильно зависит от «интеллектуальности» ПО.

Простой пример. Необходимо обработать 2 эффекта на 1 кадре. Первый эффект — обработка кадра (например — поворот кадра в плоскости, псевдо 3D эффект), второй — наложение титров по ключу. Выполнить эту обработку ЦП может несколькими способами:

Первый - последовательное выполнение эффектов. Вначале ЦП (вернее алгоритм ПО) рассчитывает новые координаты точек кадра, а затем происходит просчет наложения 2-го изображения поверх первого. При этом необходимо загрузить и выполнить две последовательности команд ЦП. Если ПО достаточно «интеллектуально», то оно проанализирует возможности загрузки обоих последовательностей в КЭШ. Иначе просто будет выполнено два цикла обращения к ОЗУ.

Второй вариант. Анализируются оба изображения на область точек перекрытия. Просчитывается возможность распараллеливания вычислений. Понятно, что область закрытая вторым изображением может не просчитываться на эффект поворота, а сразу рассчитываться по алгоритму замещения точек изображения. При этом имеется возможность одновременной загрузки, как целочисленного АЛУ, так и АЛУ для чисел с плавающей точкой, при условии возможности их одновременной работы. Выигрыш в скорости очевиден. Следует заметить, что при наличии векторного ЦП с размерностью 2048×2048 векторов, расчет данного эффекта теоретически мог занять один цикл такого ЦП.

Теперь что касается переносимости кода. При всей разнообразности платформ ЦП, основной набор команд достаточно стандартный и при наличии хороших компиляторов, не составит большой проблемы. Проблемы могут возникнуть как раз при переносе кода, например, на векторные ЦП. Что касается использования более высокого уровня команд, то в принципе так оно и есть. Большое количество эффектов сторонних разработчиков используют именно этот способ для дополнения к существующему ПО. Правда такой подход ограничивает количество ПО, на котором доступны эти эффекты.

Следует заметить и еще такой фактор. Быстро растущие мощности ЦП, при снижении стоимости и необходимость удержания на рынке, заставляют разработчиков ПО идти по интенсивному пути развития.

Александр Чемерис (admin@ailant.komi.ru)


Комментарий 3

Про векторные вычисления ничего не могу сказать, таких в нашем мире PC от Интела нет.

Про обработку изображения можно добавить к сказанному в комментарии на комментарий следующее:

Давайте спустимся на землю.

Я по молодости считал подобные «эффекты», делая расчеты двумерных и трехмерных электрических полей с учетом сложной геометрии и распределения объемных зарядов в пространстве. В некотором смысле это и был сложный видео эффект. Я имел на экране одну исходную картинку (граничные условия и распределение объемного заряда —типичная задача в физике низкотемпературной плазмы), и мне надо было по алгоритму из нее сделать другую — распределение поля.

Так вот, решение в одной точке зависело от очень многих точек исходной картинки — плотности заряда, координаты, форма электродов… Типичный случай сложного эффекта в видеомонтаже. Уверяю вас, что сложность зависимости конечного результата от начальных данных не определяет длину кода. В моем случае приходилось решать все итерационно, перебирая «пикселы» и делая над ними вычисления. Размер «картинки» был от 30×30 до 1200×1200 точек. Но, весь код содержал несколько циклов по всем точкам, в цикле было до полусотни ассемблерных команд. Делалось все на Паскале 7.0 в защищенном режиме, поэтому я мог в «куче» создать такие большие псевдомассивы. На встроенный ассемблер я перешел только по причине сильной тормознутости кода на Паскале. Там вообще никакой оптимизации не делалось. Вся программа оперировала с данными до 20 МБ, а ее код был не более 40-50 КБ и исполняемый код ЦИКЛА заведомо помещался в кэш ПЕРВОГО уровня. Не надо смешивать количество вычислений (проходов цикла) с длиной кода. Это очевидно разные вещи.

Если алгоритм общения с кэшем сделан хоть немного разумно, то последовательный перебор точек одной картинки с целью просчета их координат и откладывания значений в другой массив работает эффективно и без кэша второго уровня. Делается просто пакетное чтение из основной памяти группы байт прямо в кэш первого уровня, поскольку перебор последовательный, то все работает очень быстро. Я тогда специально исследовал (3-6 лет назад) влияние кэша и его размера на скорость счета.

Размер кэша в 386 машине ничего не значил, 64 и 128 к варианты работали просто одинаково. Выключение кэша все тормозило вдвое, но это и понятно для 386 DX40.

Размер кэша второго уровня у 486 машин тоже не имел значения. Его отключение, или использование безкэшевого варианта (ноутбук 486 DX 2 50) замедляло расчеты на 5-7%. Отключение кэша первого уровня все сильно тормозило. Здесь наличие кэша второго уровня сказывалось заметно, потому что код цикла мог не вполне помещаться в кэш первого уровня из-за его малой величины.

Лирическое отступление. Забавно, но из моих тогдашних опытов проистекло следующее наблюдение: если и код и данные программки помещались в кэш первого уровня, то на ноутбуке происходило следующее. В чистом ДОСЕ, в обычном real паскале, цикл типа a:=b*c исполнялся быстро только первую минуту. Затем все тормозилось втрое. Я не мог понять, почему не могу измерить время исполнения одной команды умножения, написав цикл из миллиона умножений и повесив сверху измеряющий время пять раз подряд цикл. После первого прохода все жутко замедлялось. В защищенном режиме, или в окне ДОС под Win3.1 все работало без тормозов. Если вместо перемножения одной пары чисел я брал массив >8К (если 4к, то я не виноват, половина полного размера кэша была) и перебирал его, то эффект замедления пропадал. Граница сидела около размера кэша данных первого уровня. Так вот, оказалось, что если весь исполняемый код и данные находятся внутри кэша первого уровня, то система энергосбережения ноутбука считала,что он просто ничего полезного не делает и снижала частоту втрое.

Разницы во времени прохода цикла с большим массивом и с маленьким, умещавшимся в кэш, в одинаковых protected code условиях я вообще не заметил. Таким образом, производительность не зависела от того, уместились все последовательно перебираемые данные в кэш или нет. Все делалось, разумеется, на плавающей точке, довольно медленно работавшей на 386\486 машинах.

На пентиуме, выключение кэша второго уровня уменьшало скорость на 3%. Размер этого кэша на скорость не влиял. Размер массива данных тоже. Процессор просто обрабатывал 4 байта новых данных за большее число тактов, чем это нужно для их извлечения в выровненном по границам в 4 байт и пакетном режиме.

На пентиуме про я с трудом смог свою старую программку запустить, спасибо Борланду. Все уже слышали, что паскаль их падает на машинах быстрее ППРО 180. Если процессор чем-нибудь отвлечь при загрузке кода, то удавалось программку запустить. Никаких чудес не произошло, а Пентиум2 300 был в полтора раза быстрее, как ему и положено.

Я полагаю, что оба эффекта из примера в комментарии к моей заметке работают-таки последовательно. Ведь это разные эффекты и написаны разными кусками кода. Кто-то выполняется раньше. А что, надо много кода для вычисления координаты точки при повороте? Мне казалось раньше, что четырех строк хватит. Два десятка ассемблерных команд. Потом, когда все повернется, можно запустить второй проход по «облагораживанию» типа antialiasing. Это и программировать и проще результат выходит предсказуемый. Для antialiasing опять кода надо мало, только считать много.

А вот теперь и потитровать можно.

Гауссовы преобразования тоже последовательным перебором пикселов с вычислениями делаются. Ничего особенного в этом случае тоже нет. Хотя для экстремистских случаев гауссового размытия на всю картинку и медленно все будет, но точка, из которой добавочки по всем другим разлетаются — одна, а выходные перебираются последовательно. Опять конвейер выходит, что для кэша равносильно его непризнанию. Не вижу я ни одного примера из приведенных, где бы КОД был длинный. Про данные я уже говорил, если над каждым пикселом надо потрудиться, то обмен с основной памятью не есть замедляющий фактор.

Декомпрессия. Включается сторонний алгоритм, обычно поставляющий на выход в память bitmap. Он работает медленнее, чем может память. Размер исполняемого кода алгоритма декомпрессии/компрессии небольшой. Данные обрабатываются последовательно, алгоритм вычислений сравнительно простой, но может быть трудоемким по числу операций. Длина последовательности команд в цикле почти наверняка небольшая.

Про векторные вычисления написано красиво. Но я в молодости лазеры бо-о-льшие делал и разрабатывал, не понять мне красоты…

Григорий Байцур (baitsur@parascript.com)