2016-05-16 4 views
2

Я выполняю побитовое НЕ операции над пикселями в изображении с использованием SSE.SSE Intrinsics - логическая НЕ оптимизация

У меня есть несколько вопросов:

  1. Может ли это быть оптимизирована дальнейшим использованием OpenMP?
  2. Есть ли узкие места в моем алгоритме, которые можно оптимизировать?

Вот мой код:

unsigned int iSSE2Size = (SrcImage1.GetHeight() * (SrcImage1.GetStepBytes() >> 1)) >> 3; 
__m128i *m_ucSrcPtr = (__m128i *)SrcImage1.GetWordPtr(); 
__m128i *m_ucDstPtr = (__m128i *)DestImage.GetWordPtr(); 
__m128i iMaxVal = _mm_set1_epi16(0xFFFF); 
unsigned short *srcRowPtr, *dstRowPtr; 
while (iSSE2Size-- > 0) 
{ 
    *m_ucDstPtr = _mm_andnot_si128(*m_ucSrcPtr, iMaxVal); 
    m_ucSrcPtr++; 
    m_ucDstPtr++; 
} 
+1

Вы пробовали разворот цикла? – Mehrdad

+1

Можете ли вы обернуть это в функцию, которая на самом деле компилируется, поэтому мы можем посмотреть на выход компилятора? –

+1

Почему бы вам просто не использовать '_mm_set1_epi16 (65535)', и пусть компилятор беспокоится о том, как получить данные там. (подсказка, она будет лучше работать, чем хранить в локальном массиве в стеке, а затем загружать оттуда). Реестр всех-тех может быть сгенерирован «на лету» с помощью 'pcmpeqw, то же самое, а CPU распознают эту идиому как не зависит от старого значения, например, для xor-обнуления. Пусть компилятор сделает это за вас.) –

ответ

0
  1. Да, вы могли бы попытаться как раскатывают цикла и использовать OpenMP для оптимизации кода.

    #pragma omp parallel for 
    for (;iSSE2Size-=2 > 0;) 
    { 
        *m_ucDstPtr = _mm_andnot_si128(*m_ucSrcPtr, iMaxVal); 
        m_ucSrcPtr++; 
        m_ucDstPtr++; 
    
        *m_ucDstPtr = _mm_andnot_si128(*m_ucSrcPtr, iMaxVal); 
        m_ucSrcPtr++; 
        m_ucDstPtr++; 
    } 
    

    Обратите внимание, что, возможно, вы можете развернуть несколько раз, чтобы повысить производительность.

  2. Я не вижу никаких узких мест в предоставленном фрагменте.

Смежные вопросы