Мне было интересно, есть ли целочисленная инструкция SSE2 / AVX2 или последовательность инструкций (или встроенных функций), которые нужно выполнить, чтобы достичь следующего результата:
Дана строка из 8-байтовых пикселей формы:
A = {a, b, c, d, e, f, g, h}
Есть ли способ загрузить эти пиксели в регистр YMM, который содержит 8 32-битных пикселей ARGB, так что начальное значение оттенков серого транслируется в другие 2 байта каждого соответствующего 32-битного пикселя? Результат должен быть примерно таким: (0 - значение альфа)
B = {0aaa, 0bbb, 0ccc, 0ddd, 0eee, 0fff, 0ggg, 0hhh}
Я полный новичок в векторных расширениях, поэтому я даже не уверен, как к этому подойти, и возможно ли это вообще.
Любая помощь будет оценена по достоинству. Спасибо!
ОБНОВЛЕНИЕ1
Спасибо за ответы. Но у меня все еще есть проблема:
Я собрал этот небольшой пример и скомпилировал его с VS2015 на x64.
int main()
{
unsigned char* pixels = (unsigned char*)_aligned_malloc(64, 32);
memset(pixels, 0, 64);
for (unsigned char i = 0; i < 8; i++)
pixels[i] = 0xaa + i;
__m128i grayscalePix = _mm_load_si128((const __m128i*)pixels);
__m256i rgba = _mm256_cvtepu8_epi32(grayscalePix);
__m256i mulOperand = _mm256_set1_epi32(0x00010101);
__m256i result = _mm256_mullo_epi32(rgba, mulOperand);
_aligned_free(pixels);
return 0;
}
Проблема в том, что после выполнения
__m256i rgba = mm256_cvtepu8_epi32(grayscalePix)
rgba содержит только первые четыре двойных слова. Последние четыре равны 0.
В руководстве для разработчиков Intel говорится:
VPMOVZXBD ymm1, xmm2 / m64
Ноль расширить 8 упакованных 8-битных целых чисел в младших 8 байтах xmm2 / m64 до 8 упакованных 32-битных целых чисел в ymm1.
Я не уверен, что это предполагаемое поведение, или я все еще что-то упускаю.
Спасибо.
-O0
, чтобы компилятор сохранял векторные операции. Даже-Og
или-O1
оптимизировали все, кроме malloc / free. Попробуйте сохранить вектор в массивеuint32_t
и распечатать его с помощьюprintf
или чего-то подобного C ++. - person Peter Cordes   schedule 09.11.2016_m256i
. Кажется, будто он обрезает их на_m128i
границе. Кроме того, окно регистров тоже не сильно помогло. Все выглядит нормально после того, как я сохранил вектор в памяти и сделалprintf
, поэтому я думаю, спасибо, что в порядке :) - person redeye   schedule 10.11.2016_m256i
в отладчике. Когда мне нужно проверить свой код на правильность, я использую#ifdef _DEBUG
код, где я просто копирую все в память и смотрю там. - person redeye   schedule 10.11.2016