Заменить байт другим

Stub помогает нам запустить тест. Как? Он дает значения, которые помогают запустить тест. Эти значения сами по себе не являются реальными, и мы создали эти значения только для запуска теста. Например, мы создаем HashMap, чтобы дать нам значения, похожие на значения в таблице базы данных. Поэтому вместо прямого взаимодействия с базой данных мы взаимодействуем с Hashmap.

Mock - это поддельный объект, который запускает тест. где мы положим assert.

0
задан senseiwa 15 January 2019 в 15:32
поделиться

1 ответ

Что вам по сути нужно сделать, это установить все байты (входных данных), которые вы хотите заменить, на ноль. Затем установите все остальные байты подстановки в ноль и ИЛИ результаты. У вас уже есть маска для этого из _mm_cmpeq_epi8. В целом, это можно сделать так:

__m128i mask = _mm_cmpeq_epi8(inp, val);
return _mm_or_si128(_mm_and_si128(mask, sub), _mm_andnot_si128(mask, inp));

Поскольку последняя комбинация и / и не / или очень распространена, SSE4.1 ввел команду, которая (по существу) объединяет их в одну:

__m128i mask = _mm_cmpeq_epi8(inp, val);
return _mm_blendv_epi8(inp, sub, mask);

На самом деле, clang5.0 и более поздние версии достаточно умны, чтобы заменить первый вариант вторым при компиляции с оптимизацией: https://godbolt.org/z/P-tcik


Примечание: если значение подстановки действительно 0x01, вы можете использовать тот факт, что маска (результат сравнения) равна 0x00 или 0xff (то есть -0x01). ), т. е. вы можете обнулить значения, которые хотите заменить, и затем вычесть маску:

__m128i val = _mm_set1_epi8(0x06);
__m128i mask = _mm_cmpeq_epi8(inp, val);
return _mm_sub_epi8(_mm_andnot_si128(mask, inp), mask);

Это может сохранить либо загрузку вектора 0x01 из памяти, либо потерю для него регистра. И в зависимости от вашей архитектуры он может иметь немного лучшую пропускную способность.

0
ответ дан chtz 15 January 2019 в 15:32
поделиться