Skip to Content

О векторном умножении: нет гигапикселя в секунду

Тема матричного цветопреобразования не отпускает нас.

Наш читатель maratyszcza намекает нам, что haddps - тоже хорошая инструкция.

Его вариант вы найдете по вышеуказанной ссылке, а я потестировал вариант попроще, без unroll, без префетча, без одновременной обработки половинок данных. Исключительно для совместимости с прошлыми тестами:

  1. ALIGN1(32) float _m_zero[8] ALIGN2(32) = {0.f,0.f,0.f,0.f, 0.f,0.f,0.f,0.f};
  2. void perm256(float data[], int sz)
  3. {
  4.         int i;
  5.         __m256 m0 = _mm256_load_ps(matX2[0]);
  6.         __m256 m1 = _mm256_load_ps(matX2[1]);
  7.         __m256 m2 = _mm256_load_ps(matX2[2]);
  8.         __m256 zero = _mm256_load_ps(_m_zero);
  9.  
  10.         for(i=0;i<sz/2;i++)
  11.         {
  12.                 __m256 ymm2 = _mm256_load_ps(&data[i*8]);
  13.                 __m256 ymm0 = _mm256_mul_ps(ymm2,m0);
  14.                 __m256 ymm1 = _mm256_mul_ps(ymm2,m1);
  15.                 ymm2 = _mm256_mul_ps(ymm2,m2);
  16.                 ymm0 = _mm256_hadd_ps(ymm0,ymm1);
  17.                 ymm2 = _mm256_hadd_ps(ymm2,zero);
  18.                 ymm0 = _mm256_hadd_ps(ymm0,ymm2);
  19.                 _mm256_store_ps(&data[i*8],ymm0);
  20.         }
  21. }
Три dpps и два blendps меняем на три умножения и три горизонтальных сложения результат завораживает:
  • 1031 Mpix/sec с интеловским компилятором, который, отчего-то не грузит значение в регистр, а прямо ymmword ptr лепит в mulps, но зато переупорядочивает инструкции.
  • 1063 Mpix/sec с Visual C++, который делает все прямо как написано.

Update: к сожалению, я при тестировании ошибся в инварианте цикла и реальность не такая великолепная: 725 Mpix/sec. Да, быстрее, чем все что было раньше, но не в полтора раза, как показалось изначально.

Comments

Ололо, марат!

Ололо, марат!

Вот смотрю и не могу понять.

Вот смотрю и не могу понять. Количество проходов цикла увеличилось в 8 раз (i+=8 супротив i++), а скорость уменьшилась ~ в 1.5 раза. Получается в предыдущем варианте уперлись во что-то (память/данные не в кэше)? И для данной реализации более 2-х потоков не имеет смысла? Или там неинициализированный ymm15 покопался?

Естественно, это утыкается в

Естественно, это утыкается в cache misses. Если мы идем с шагом 256 байт, то все (относительно) плохо, L1 страдает дважды: и от misses и в ассоциативность ему больно бьют постоянно.

Только не в 8, а в 4, у меня было меньше sz и +=8, а стало sz/2 и ++.

Что же до числа потоков, то много я не экспериментировал, а банальное #pragma omp parallel for
(и даже если сделать большими кусками и на куски звать эту подпрограмму) - дает очень мало. Ну может процентов 20.

ymm15 не копался - в программе у меня все называется регистрами, а при переносе в блог я имена переменных сделал покрасивее, а это место - изначально забыл.

Так то у меня оно даже проверяется после прогона, все ли правильно (первые 128 значений, конечно).

Понятно. Спасибо.Про 8 и

Понятно. Спасибо.
Про 8 и 4.
Значит при переносе в блог так поправилось. Я себе copy/paste сделал в надежде посмотреть на компе, но не добрался с AVX. Тогда еще и удивился про объявленный и не используемый zero, необъявленный и неинициализированный ymm15 и про i=0;i<sz/2;i+=8  data[i*8]. Подумал кусок кода просто для иллюстрации идеи и команды asm-овые мне незнакомые, надобы повнимательнее на досуге посмотреть. И заодно на нумерацию строк поругался. Погоглил, заглянул а как это у других делается. А тут и новая версия появилась. Про 4 раза наверное и не стал бы писать. Но это мелочи.

Тшорт. Оно кушает. Ну значит

Тшорт. Оно кушает. Ну значит ненужное было. :-)

<code> лечит нас.Может и в

<code> лечит нас.

Может и в 8, сейчас уже не вспомню, а в vcs это не клал.

А ошибки я правлю, когда посты перечитываю. Ошибки бывают, потому что в блог попадает концепт, а не реальный код (а в реальном коде может быть десяток #ifdef для разного префетча - если я его тестирую).

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <s> <i> <b> <blockquote>
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>, <c>, <cpp>, <drupal5>, <drupal6>, <java>, <javascript>, <php>, <ruby>. The supported tag styles are: <foo>, [foo].
  • Images can be added to this post.

More information about formatting options



.