Гайдзинам с любовью. Сони.

May 04, 2007 11:22

Купил на днях чудо-приставку PS3. Приставка просто так не включается, нужен монитор с поддержкой HDCP. На агрегат с поддержкой 1080p любви к Сони у меня не хватило, приобрел "простенький" 22 дюймовый монитор с поддержкой 720p.

Встроенная Game OS в русской транскрипции забавна. "Отформатировать утилиту" - "Format Utility". Заставка могильного цвета - говорят, что ее цвет зависит от месяца. Хочу зелененькую. Или желтенькую. Или синенькую - по желанию, а не в зависимости от фазы луны. Тормозит. Впрочем, эта самая Game OS была мне плоско-параллельна. Только для того, чтобы установить linux bootloader.

Дистрибутив YDL установился как легкий ветерок. Как обычно, совершил ужасную ошибку - выбрал русский язык в качестве системного. Каждый раз, когда ставлю новый дистрибутив, зачем-то делаю так. Раскаиваюсь, конечно, но поздно. В этот раз почти все шрифты отображались. Где-то половина, остальные - квадратиками. Это безусловный прогресс по сравнению с предыдущими наблюдениями.



Шаловливые ручки сразу потянулись к libspe. Пример почти сразу откомпилировался и заработал. За вычетом грустных нубовских ошибок. Ну там пробелы в makefile вместо tabs. Ну там некратный 16 размер DMA пакета для посылки на SPU - bus error. Ну там функция clock() не работала, выдавала константный 0 - в ответ я заюзал функцию spu_read(write)_decrementer ( пример найден на блоге японского товарища на японском языке ) и получил счастье.

Хотелось peak, то есть - сияющих высот. Естественно, на стандартной задаче - умножении матриц. Пик тут простой - simd float4 fmad на SPU за такт ( 8 flops ). На одном SPU должно получиться 24 гигафлопа. Параллельно с multiply-add может запускаться load-store.

Сишный вариант не зажог, до гигафлопа не дотянул. Я не растерялся, взял интринсики.

vec_float4 *a = &pd.a;
vec_float4 *b = &pd.b;

for( i = 0; i < 256; i += 4 )
{
r0 += a[i] * b[i] +
a[i + 1] * b[i + 1] +
a[i + 2] * b[i + 2] +
a[i + 3] * b[i + 3];
}

Посчитал в уме, что код будет давать 12 гигафлоп, потому что темп загрузки-выгрузки двойной по сравнению с математикой. Откомпилировал (-O3), запустил: 3.2 гигафлопа. Смотрю листинг:

http://rafb.net/p/BQMhrV71.html

Вижу страшное. Обратите внимание на блок fma в конце. Зависимая цепочка - команды встали "друг над другом". Вместо одного такта - 6 каждая. Установка скобочек ( + ) + ( + ) в коде помогла чуть. И по мелочевке - левые и правые команды не захотели спариться. "Я тогда цежу сквозь зубы, но уже конечно грубо..." Написал

for( i = 0; i < 256; i += 4 )
{
r0 += a[i] * b[i];
r1 += a[i + 1] * b[i + 1];
r2 += a[i + 2] * b[i + 2];
r3 += a[i + 3] * b[i + 3];
}

Стало маргинально лучше, но команды все равно не спаривались.

Почесал нос. Вспомнил, как консольные люди говорили мне: "прежде всего, макроассемблер с удобной подсветкой синтаксиса захочешь ты"... Макроассемблер с удобной подсветкой синтаксиса нужен мне, да.

Засыпал, думал, что удобного языка для написания под SPU не придумали еще. Хочется писать симпатичный код вроде

foreach( object in sceneObjects | IsIn( object->GetBoundingBox(), cameraFrustrum ) )object->Draw();

Хочется счастья - в функции не задумываться о том, что происходит на нижних уровнях. Хочется, чтобы этот самый foreach генерировал серию DMA запросов на код виртуальных функций и на данные. Параллельно обрабатывал.

Функция становится объектом неминуемо. Контекст работы функции - тоже объект. Получается какой-то функциональный язык с императивным подъязыком. Сразу хочется GC и компактификации в пределах SPU local storage.

Если мир Haskell и мир макроассемблера встретится - будет счастье на SPU. "Покамест лес Бирнамский не двинулся на Дунсинанский холм, мне страх неведом."

Previous post Next post
Up