11-08-2004 17:49 [IPP] Логические операции
Всё та же Intel Performance Primitives Library, версия 3.0 (ранее по теме: 1, 2, 3).

Есть группа функций, которые должны делать примерно следующее:
для всех x из [left, right)
{
  для всех y из [bottom, top)
  {
    dst[x, y] = src[x, y] @ value;
  }
}

где @ — логическая операция из {and, or, xor, shift left, shift right}.

Подсовываем ей картинку, заXORиваем в ней прямоугольник… скажем, left=54 bottom=0 right=55 top=64. Смотрим результат, на результате закрашена толстая полоса шириной в 10 пикселов WTF?

Берём противогаз и ныряем в дизассемблер.

Оказывается, для скорости функция реализована так, чтобы xor’ить через SSE блоками сразу по 16 байт. Естественно, выглядит примерно так:
если (pSrc не делится на 16)
{
  обработать левый неполный блок ширины (16 - pSrc mod 16);
}
обработать средние полные блоки;
если (pSrc + width не делится на 16)
{
  обработать правый неполный блок ширины ((pSrc + width) mod 16);
}

Опять-таки естественно, случай, когда вся запрошенная область лежит в одном 16-пиксельном блоке, не рассматривается. В документации — про эту оптимизацию ни слова. Удобно.

Что будет, когда ей дадут выделенный на стеке буфер размера, не кратного 16, и начнут xor’ить (or’ить, and’ить, сдвигать) короткие отрезки близко к концу — страшно подумать. Блин.

Что интересно — аналогичные функции для @ из {+, -, *, /} ведут себя вполне пристойно и предсказуемо.
Закрыть