Подтвердить что ты не робот

Что делает Apple PowerPC memcpy настолько быстрым?

Я написал несколько функций копирования в поисках хорошей стратегии памяти на PowerPC. Использование регистров Altivec или fp с подсказками кеша (dcb *) удваивает производительность по сравнению с простым байтовым циклом копирования для больших данных. Первоначально довольный этим, я бросил регулярную memcpy, чтобы увидеть, как он сравнивается... в 10 раз быстрее, чем мой лучший! Я не собираюсь переписывать memcpy, но я надеюсь научиться этому и ускорить несколько простых фильтров изображений, которые тратят большую часть времени на перемещение пикселей в память и из памяти.

Акустический анализ показывает, что их внутренний цикл использует dcbt для предварительной выборки, с 4-мя векторными чтениями, затем записывается 4 вектора. После настройки моей лучшей функции, чтобы также перехватить 64 байта на итерацию, преимущество производительности memcpy по-прежнему неловко. Я использую dcbz для освобождения полосы пропускания, Apple ничего не использует, но оба кода имеют тенденцию колебаться в магазинах.

prefetch
  dcbt future
  dcbt distant future
load stuff
  lvx image
  lvx image + 16
  lvx image + 32
  lvx image + 48
  image += 64
prepare to store
  dcbz filtered
  dcbz filtered + 32
store stuff
  stvxl filtered
  stvxl filtered + 16
  stvxl filtered + 32
  stvxl filtered + 48
  filtered += 64
repeat

Есть ли у кого-нибудь идеи о том, почему очень похожий код имеет такой драматический разрыв в производительности? Я бы хотел помассировать настоящие фильтры изображений в любом секретном соусе, который использует memcpy!

Дополнительная информация: Все данные выравниваются по вектору. Я делаю отфильтрованные копии изображения, не заменяя оригинал. Код работает на PowerPC G4, G5 и Cell PPU. Версия Cell SPU уже безумно быстро.

4b9b3361

Ответ 1

Акустический анализ показывает, что их внутренний цикл использует dcbt для предварительной выборки, с 4-мя векторными чтениями, затем записывается 4 вектора. После настройки моей лучшей функции, чтобы также перехватить 64 байта на итерацию

Я могу заявить очевидное, но, поскольку в вашем вопросе не упоминается следующее: возможно, стоит указать:

Я бы пообещал, что выбор Apple из 4 векторов, за которыми следуют 4 вектора, пишет так же, как и с конвейером G5, порядок выполнения заказа в "группах отправки" , поскольку он имеет магический 64-байтовый идеальный размер линии. Вы заметили, что линия пропускает в Nick Bastin ссылку bcopy.s? Это означает, что разработчик подумал о том, как поток команд будет потребляться G5. Если вы хотите воспроизвести одну и ту же производительность, недостаточно прочитать данные по 64 байта за раз, вы должны убедиться, что ваши группы команд заполнены (в основном, я помню, что инструкции могут быть сгруппированы до пяти независимых, первые четыре - инструкции без прыжка, а пятый - только прыжок. Подробности сложнее).

EDIT: вас также может заинтересовать следующий параграф на той же странице:

Инструкция dcbz по-прежнему выравнивает 32 байтовые сегменты памяти в соответствии с G4 и G3. Однако, поскольку это не полная кегли на G5, у него не будет преимуществ в производительности, на которые вы, вероятно, надеялись. Существует инструкция dcbzl, недавно введенная для G5, которая нулевая полная 128-байтная шкала.

Ответ 2

Я не знаю точно, что вы делаете, так как я не могу видеть ваш код, но секретный соус Apple - здесь.

Ответ 3

Возможно, это из-за кэширования процессора. Попробуйте запустить CacheGrind:

Cachegrind - это профилировщик кеша. Это выполняет детальное моделирование I1, D1 и L2 в вашем CPU и поэтому можно точно определить источники пропусков кеша в вашем коде. Это определяет количество промахов в кэше, ссылки на память и инструкции выполняется для каждой строки исходного кода, с функцией, для каждого модуля и резюме всей программы. Это полезно с программами, написанными на любом языке. Cachegrind запускает программы о 20-100x медленнее, чем обычно.

Ответ 4

Все еще не ответ, но вы подтвердили, что memcpy фактически перемещает данные? Возможно, это было просто перепрограммированное копирование на запись. Вы все равно увидите внутренний цикл memcpy в Shark, поскольку часть первой и последней страниц действительно скопирована.

Ответ 5

Как уже упоминалось в другом ответе, "dcbz", как определено Apple на G5, работает только на 32 байтах, поэтому вы потеряете производительность с этой инструкцией на G5, который имеет 128 байтов. Вам нужно использовать "dcbzl", чтобы предотвратить кэширование адресата из памяти (и эффективно сократить полезную ширину памяти для чтения в два раза).