Многопоточная встроенная сборка

Я пытаюсь быстро создать большое количество хэшей sha256 на машине T4. У T4 есть инструкция ‘sha256’, которая позволяет мне вычислять хэш в одном операционном коде. Я создал встроенный шаблон сборки для вызова кода операции sha256:

в моем коде C ++:

extern "C"{
void ProcessChunk(const char* buf, uint32_t* state);
}

pchunk.il:

.inline ProcessChunk,8
.volatile
/* copy state */
ldd [%o1],%f0 /* load 8 bytes */
ldd [%o1 + 8],%f2 /* load 8 bytes */
ldd [%o1 +16],%f4 /* load 8 bytes */
ldd [%o1 +24],%f6 /* load 8 bytes */

/* copy data */
ldd [%o0],%f8 /* load 8 bytes */
ldd [%o0+8],%f10 /* load 8 bytes */
ldd [%o0+16],%f12 /* load 8 bytes */
ldd [%o0+24],%f14 /* load 8 bytes */
ldd [%o0+32],%f16 /* load 8 bytes */
ldd [%o0+40],%f18 /* load 8 bytes */
ldd [%o0+48],%f20 /* load 8 bytes */
ldd [%o0+56],%f22 /* load 8 bytes */

sha256
nop

std %f0, [%o1]
std %f2, [%o1+8]
std %f4, [%o1+16]
std %f6, [%o1+24]
.end

В однопоточной среде все работает отлично, но недостаточно быстро. Я использовал openmp для распараллеливания приложения, чтобы я мог вызывать ProcessChunk одновременно. Многопоточная версия приложения работает нормально для нескольких потоков, но когда я увеличиваю количество потоков (например, 16), я начинаю получать фиктивные результаты. Входными данными для функции ProcessChunk являются переменные стека, локальные для каждого потока. Я подтвердил, что входные данные генерируются правильно, независимо от количества потоков. Если я помещаю ProcessChunk в критическую секцию, я получаю правильные результаты, но производительность значительно снижается (один поток работает лучше). Я поставлен в тупик, в чем может быть проблема. Возможно ли для потоков Solaris наступать на регистры с плавающей запятой другого потока?

Любые идеи, как я могу отладить это?

С уважением

Обновить:

Я изменил код, чтобы использовать четырехмерную (16 байтную) нагрузку, и сохранил:

.inline ProcessChunk,8
.volatile
/* copy state */
ldq [%o1],    %f0
ldq [%o1 +16],%f4

/* copy data */
ldq [%o0],   %f8
ldq [%o0+16],%f12
ldq [%o0+32],%f16
ldq [%o0+48],%f20

lzd %o0,%o0
nop

stq %f0, [%o1]
stq %f4, [%o1+16]
.end

На первый взгляд проблема, кажется, ушла. Производительность значительно снижается после 32 потоков, так что это число, которое я придерживаюсь (по крайней мере, на данный момент), и с текущим кодом я, кажется, получаю правильные результаты. Я, вероятно, просто замаскировал проблему, поэтому собираюсь провести дальнейшие тесты.

Обновление 2:

Я нашел время, чтобы вернуться к этому, и я смог получить приличные результаты от T4 (10 миллионов хешей в минуту).

Изменения, которые я сделал, были:

  1. Используется сборка вместо встроенной сборки
  2. Поскольку функции были листовыми функциями, я не трогал окно регистрации

Я собрал все в библиотеке и сделал код доступным Вот

4

Решение

Не эксперт по архитектуре Spark (я могу ошибаться), но вот мое предположение:

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

Как это работает для двух потоков? Оба вызова ProcessChunk будут пытаться скопировать разные входные значения в одни и те же регистры ЦП.

Обычно я вижу, что регистры ЦП в ассемблерном коде похожи на «глобальные» переменные для языка программирования высокого уровня.

Сколько ядер у вашей системы? Может быть, вы в порядке, пока у вас нет потока на ядро ​​/ набор аппаратных регистров. Но это также подразумевает, что поведение кода может зависеть от того, как запланированы потоки в разных ядрах вашей системы.

Знаете ли вы, как система ведет себя, когда она планирует потоки из того же процесса на ядре процессора? Я имею в виду: хранит ли система регистры незапланированного потока, как при переключении контекста?

Тест, который я бы запустил, состоит в том, чтобы порождать количество потоков, равное N ядер ЦП, а затем запустить тот же тест с N + 1 (я предполагаю, что для каждого ядра ЦП установлен регистр с плавающей запятой).

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]