SSE2 преобразует упакованные RGB в пиксели RGBA (добавляет 4-й байт 0xFF после каждых 3 байтов)
Мое приложение обрабатывает вычислительно тяжелую нагрузку, близкую к реальному времени, и мне нужно максимально ускорить ее. Программное обеспечение написано на C++ и предназначено только для Linux.
Моя программа получает 6,4-мегапиксельный RAW-буфер данных со специальной астрономической камеры, которая способна выдавать 25 кадров в секунду при разрешении 3096px x 2080px. Затем этот поток удаляется в реальном времени с использованием высококачественного алгоритма удаления линейной интерполяции. Я знаю, что алгоритм распада HQ с линейной интерполяцией всегда будет тяжелым в вычислительном отношении, но есть и другие области моей программы, которые я хотел бы ускорить.
После того, как поток был разрушен, мне нужно преобразовать буфер RGB (созданный из дебаяя) в буфер RGBA, потому что я понимаю (доказано профилированием), что графические процессоры работают более эффективно на пиксельных буферах RGBA. Тем не менее, я рад быть исправленным в этом.
Изначально я написал очень простой цикл for (ниже), который, конечно, дал ужасные результаты.
// both buffers have uint8_t elements
for(int n = 0, m = 0; n < m_Width * m_Height * 4; n+=4, m+=3)
{
m_display_buffer[n] = in_buffer[m];
m_display_buffer[n+1] = in_buffer[m+1];
m_display_buffer[n+2] = in_buffer[m+2];
m_display_buffer[n+3] = 255;
}
Приведенный выше код дал мне частоту кадров 13 кадров в секунду. Мой следующий эксперимент состоял в том, чтобы инициализировать буфер со всеми элементами, равными 255, а затем использовать следующий код:
uint8_t *dsp = m_display_buffer;
uint8_t *in_8 = (uint8_t*) in_buffer;
for (int n = 0; n < m_Width * m_Height; n++)
{
*dsp++ = *in_8++;
*dsp++ = *in_8++;
*dsp++ = *in_8++;
*dsp++;
}
Приведенный выше код значительно ускорил цикл; сейчас он достигает 23,9 кадров в секунду на ноутбуке i7-7700. Тем не менее, запуск этого кода на старых машинах все еще дает очень разочаровывающую частоту кадров. Я знаю, что старые машины борются с распадом, но профилирование ясно показывает, что преобразование в буфер RGBA вызывает значительные проблемы.
Я читал, что, возможно, можно использовать встроенные функции SSE, чтобы сделать это гораздо более эффективно, однако у меня нулевой опыт использования встроенных функций SSE.
Я пробовал много примеров SSE, найденных в сети, но не могу заставить его работать. Поэтому я был бы благодарен, если бы кто-нибудь, имеющий опыт работы с SSE, смог помочь мне с этой проблемой.
Я не могу выбрать SSE выше 2 или, возможно, 3, потому что мое программное обеспечение может работать на более старом оборудовании.
Я был бы признателен, если бы кто-нибудь смог указать мне правильное направление.