Черная консоль и неуспехи.

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

Пост про черную консоль будет выдержан в черных тонах.

С самого начала PS3 была WoW фактором. SPU изумляли мощью и красотой. Но с первого же момента знакомства разные червячки сомнения терзали меня.

Первым червячком была задача про гистограмму. Есть входной массив байт, надо посчитать гистограмму из 256 значений. Была реализация на CUDA, которая индексировала со скоростью вроде 7 гигабайт в секунду. Я прикидывал, что два SPU разделают под орех дурацкую нвидиевскую архитектуру. В IBM Cell SDK накопал пример, который как раз гистограммы и считает. Мое изумление, но на одном SPU получалось 0.7 гигабайт в секунду. Вяло. На каждый байт приходилось чтение, запись, шаффл и арифметика. Молодцы из IBM удачно развели по латентностям, но… Все одно – даже с 6 SPU получается полный отсос. Я сильно думал, как заиспользовать SIMD, но так ничего и не надумал.

Вторым червячком была задача про хеш строк. http://users.livejournal.com/_foreseer/26491.html#cutid1

Наперво показалось что один SPU порвет PC в десять раз. По всем спекам выходило. Да и по предварительным тестам, я уже пост наизготовился писать в блог. Авотхуй. Но обо всем по порядку.

Итак. Что умеет DMA engine SPU. В числе прочего умеет он собирающие ( gather ) чтения. Ты указываешь массив из пар ( указатель, длина ). Указываешь место в локальной памяти, куда собирать, рассеянные в памяти данные укладываются туда последовательно. Все это происходит асинхронно.

Я хотел определять попадание в хеш сразу для десятков ( или сотен ) строк. И через это побеждать. Сначала читаем строки, считаем по ним хеши. Делаем DMA gather из хеш-ячеек. Потом еще один раз делаем DMA gather, поскольку данные в хеш-таблице хранятся с одним уровнем косвенности, строки все же. Потом сравниваем.

Строки я хранил SIMD группами по 16 байт. Сразу написался быстрый и качественный хеш. В котором совсем не было ветвлений и который считался в среднем десять что ли тактов на строку. Кунштюками можно и быстрее, но я ликовал и так. Сравнения строк написались тоже очень быстрые. Написались DMA gather операции, все летало, пока строк было мегабайт суммарного объема. Как только их стало 10 мегабайт – скорость просела ниже плинтуса. Стал разбираться, писать тестовые примеры на DMA gather доступ.

Паттерн доступа такой – генерится DMA list на загрузку кусков данных размером по 16 байт, случайно распределенных в куске памяти. Выполнение хронометрируется, задача запускается на одном SPU. Пока кусок памяти меньше мегабайта – то я получаю примерно 100 миллионов запросов в секунду. Что соответствует 50 миллионам поискам строчки в хеше в секунду. Как только кусок памяти больше мегабайта – швах. Опытным путем установил, что дело не в мегабайте, а в числе активных страниц памяти ( по четыре килобайта ). Пока их меньше 256, то мы отлично живем. Когда больше – то выпадаем из TLB кеша. И получаем 6 миллионов запросов в секунду… Что эквивалентно 3 миллионам поискам строки в хеше.

Чудес нет, SPU оперируют в том же страничном адресном пространстве, что и центральный процессор.

Стал думать как мапить большие страницы. Включил в своем ядре Линукса поддержку больших страниц памяти. При попытке отмапить хоть одну страничку система повисла навечно в свопе. День мучений – и плюнул.

Вот такой противный червячок. Интересно, а в играх те же 4K страницы – или почти плоская память? Поди секрет…

  • http://nesnausk.org ReJ

    Статья как включить поддержку больших страниц в Линуксе под PS3 (сам ещё непробовал):
    http://www.cellperformance.com/articles/2007/01/howto_huge_tlb_pages_on_ps3_li.html

  • zap

    Может всё-таки выпадаем не из TLB кэша а из банального процессорного кэша? Он ведь по идее как раз в десяток раз быстрее чем обычная память должен быть, иначе бы игра не стоила свеч.

    А можно пару вопросов любопытного прохожего насчёт PS3? Насколько я понимаю, Linux там работает как бедный родственник чернорабочим на ферме богатого дядюшки, а как он использует видеокарту? Неужели в режиме framebuffer без акселерации вообще? И сколько он видит процессоров?

    И ещё: игры там в каком окружении запускаются? Что-то линуксообразное или нет? Вы где-то упоминали какие-то библиотеки из SDK, они статические или динамические?

  • IronPeter

    Так, не заметил коммент.

    DMA запросы не кешируются. То есть они могут фетчить из кеша – но в кеш данные не помещают. Гигабайты в секунду прямого доступа из памяти SPU в принципе близки к десяткам гигабайтов в секунду чтения из кеща на процессоре. DMA запросы – отнюдь не медленно.

    >Неужели в режиме framebuffer без акселерации вообще? И сколько он видит процессоров?

    Именно в режиме фреймбуффер. Я немножко отковырял, получил доступ к RSX с 3D. Дырочку закрыли, отковыривать по второму разу лень. Видит он 6 SPU, две нити на PPU.

    >И ещё: игры там в каком окружении запускаются? Что-то линуксообразное или нет? Вы где-то упоминали какие-то библиотеки из SDK, они статические или динамические?

    Там все очень просто. Игры запускаются под управлением GameOS, которая так же относится к гипервизору, как ядро линукса. Схематично: l1 – это гипервизор, l2 – это OtherOS/GameOS, l3 – пользовательский режим линукса/или игры. GameOS – что-то странное и проприетарное. Умельцы смогли запустить свой код под gameOS, но системные вызовы не осилили. В результате не смогли изготовить Hello World.

    Никакой официальной информации по PS3 SDK ( и NDA ) у меня нет. Сомнительно, чтобы я упоминал библиотеки из официального SDK.