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

Я пытаюсь быстро создать большое количество хэшей 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. Поскольку функции были листовыми функциями, я не трогал окно регистрации

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

1 ответ

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

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

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

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

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

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

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

Другие вопросы по тегам