Всё та же 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’ить, сдвигать) короткие отрезки близко к концу — страшно подумать. Блин.
Что интересно — аналогичные функции для @ из {+, -, *, /} ведут себя вполне пристойно и предсказуемо.