2013-10-04 4 views
1

Я пытаюсь оптимизировать некоторый код, чтобы сократить как можно больше времени выполнения. Это код:Как я могу оптимизировать этот код с помощью ARM NEON?

int shifter=0; 

    // now iterate through all the pairings 
    UINT32_ALIAS* ptr2=(UINT32_ALIAS*)ptr; 
    const BriskShortPair* max=shortPairs_+noShortPairs_; 
    for(BriskShortPair* iter=shortPairs_; iter<max;++iter){ 
     t1=*(_values+iter->i); 
     t2=*(_values+iter->j); 
     if(t1>t2){ 
      *ptr2|=((1)<<shifter); 

     } // else already initialized with zero 
     // take care of the iterators: 
     ++shifter; 
     if(shifter==32){ 
      shifter=0; 
      ++ptr2; 
     } 
    } 

мне было интересно, если это возможно, каким-то образом распараллелить, используя NEON. Возможно ли это? Спасибо

EDIT: Контекст этого кода является BRISK детектора функции (http://www.asl.ethz.ch/people/lestefan/personal/BRISK) Я пытаюсь оптимизировать этот код для архитектуры ARM. Кусок кода я имею в виду имеет следующую структуру:

-an внешнего для цикла, который сканирует определенное количество точек

-для каждой из этих точек там определенное количество других точек вокруг это (фиксированное число), и каждый из них имеет значение интенсивности.

Внутри внутреннего для цикла фиксированные пары точек сравниваются по их значению интенсивности, и результат этого сравнения может быть 0 или 1, и это значение помещается в вектор.

Код, который я разместил здесь, является внутренним для цикла.

+0

Я не прошу кода, я просто пытаюсь понять, есть ли способ оптимизировать исходный код через NEON. Поскольку я не эксперт NEON, я даже не знаю, может ли то, что я прошу, это возможно. Если это так, я собираюсь реализовать его сам. Мне нужен только общий совет по поводу осуществимости. – user2696208

+0

Без контекстного/компилируемого кода, единственное, что я могу предложить на этом этапе, - это _hint_ компилятору, что это должно быть векторизовано/будет полезно для векторизации. См. Http://stackoverflow.com/questions/14256156/how-to-give-hint-to-gcc-about-loop-count для параметров. –

+1

Я отредактировал ответ, добавив больше контекста. – user2696208

ответ

3

EDIT: Первоначально я неправильно понял исходный код. Вот правильная версия, полностью переписанная. (55 циклов/итераций)

Хотя это не так просто, как предполагалось в первоначальной версии ниже, NEON может справиться с этим очень хорошо, в результате чего повышается производительность по сравнению с первоначальной реализацией C.

С правильными настройками вы можете получить дополнительный выигрыш в производительности (менее 50 циклов/итераций). Однако читаемость будет сильно зависеть.

Удачи!

AREA BRISK_ASM_NEON, CODE, READNOLY 
    EXPORT yourFunction 
    CODE32 

yourFunction FUNCTION 

loop 
    pld  [r0, #192] 
    vld2.32  {q8, q9}, [r0]! 
    vld2.32  {q10, q11}, [r0]! 
    pld  [r0, #192] 
    vld2.32  {q12, q13}, [r0]! 
    vld2.32  {q14, q15}, [r0]! 

    vcgt.u32 q8, q8, q9 
    vcgt.u32 q9, q10, q11 
    vcgt.u32 q10, q12, q13 
    vcgt.u32 q11, q14, q15 

    pld  [r0, #192] 
    vld2.32  {q12, q13}, [r0]! 
    vld2.32  {q14, q15}, [r0]! 
    pld  [r0, #192] 
    vld2.32  {q0, q1}, [r0]! 
    vld2.32  {q2, q3}, [r0]! 

    vcgt.u32 q12, q12, q13 
    vcgt.u32 q13, q14, q15 
    vcgt.u32 q14, q0, q1 
    vcgt.u32 q15, q2, q3 

    vsli.32  q8, q10, #8 
    vsli.32  q9, q11, #8 
    vsli.32  q8, q12, #16 
    vsli.32  q9, q13, #16 
    vsli.32  q8, q14, #24 
    vsli.32  q9, q15, #24 

    vsli.8  d16, d17, #2 
    vsli.8  d18, d19, #2 
    vsli.8  d16, d18, #4 

    vbic.i8  d16, #0xaa 
    vshr.u64 d17, d16, #31 
    vorr  d16, d16, d17 

    vst1.32  {d16[0]}, [r1]! 

    subs  r2, r2, #32 
    bgt  loop 

    bx lr 

    ENDFUNC 
    END 

=========================================== ==================================

!!!!!!! Код ниже НЕВЕРЕН !!!!!!!!

====================================================================================================================================== ================================

Это кусок пирога с НЕОН.

Вот ваш "чудо":

прототип: недействительным yourFunc (беззнаковое INT * pPair, беззнаковое INT * ptr2, неподписанные кол целое);

AREA BRISK_ASM_NEON, CODE, READNOLY 
    EXPORT yourFunction 
    CODE32 

yourFunction FUNCTION 
    adr r12, shifter_table 
    vpush {q4-q7} 
    vldmia r12, {q0-q7} 

loop 
    vld1.32 {q8, q9}, [r1] 
    vorr q10, q8, q0 
    vorr q11, q9, q1 
    vld2.32 {q12, q13}, [r0]! 
    vld2.32 {q14, q15}, [r0]! 
    vcgt.u32 q12, q12, q13 
    vcgt.u32 q13, q14, q15 
    vbsl q12, q10, q8 
    vbsl q13, q11, q9 
    vst1.32 {q12, q13}, [r1]! 

    vld1.32 {q8, q9}, [r1] 
    vorr q10, q8, q2 
    vorr q11, q9, q3 
    vld2.32 {q12, q13}, [r0]! 
    vld2.32 {q14, q15}, [r0]! 
    vcgt.u32 q12, q12, q13 
    vcgt.u32 q13, q14, q15 
    vbsl q12, q10, q8 
    vbsl q13, q11, q9 
    vst1.32 {q12, q13}, [r1]! 

    vld1.32 {q8, q9}, [r1] 
    vorr q10, q8, q4 
    vorr q11, q9, q5 
    vld2.32 {q12, q13}, [r0]! 
    vld2.32 {q14, q15}, [r0]! 
    vcgt.u32 q12, q12, q13 
    vcgt.u32 q13, q14, q15 
    vbsl q12, q10, q8 
    vbsl q13, q11, q9 
    vst1.32 {q12, q13}, [r1]! 

    vld1.32 {q8, q9}, [r1] 
    vorr q10, q8, q6 
    vorr q11, q9, q7 
    vld2.32 {q12, q13}, [r0]! 
    vld2.32 {q14, q15}, [r0]! 
    vcgt.u32 q12, q12, q13 
    vcgt.u32 q13, q14, q15 
    vbsl q12, q10, q8 
    vbsl q13, q11, q9 
    vst1.32 {q12, q13}, [r1]! 

    subs r2, #32 
    bgt loop 

    vpop {q4-q7} 
    bx lr 

    ENDFUNC 

shifter_table 
    DCD (1<<00), (1<<01), (1<<02), (1<<03), (1<<04), (1<<05), (1<<06), (1<<07), (1<<08), (1<<09), (1<<10), (1<<11), (1<<12), (1<<13), (1<<14), (1<<15) 
    DCD (1<<16), (1<<17), (1<<18), (1<<19), (1<<20), (1<<21), (1<<22), (1<<23), (1<<24), (1<<25), (1<<26), (1<<27), (1<<28), (1<<29), (1<<30), (1<<31) 

    END 

Код выше только умеренно оптимизирован (блокировочный здесь и там), и работает только если количество кратно 32.

Это, насколько я иду управление читаемостью и при работе «непрофессионально» ,

47 циклов/итерация не плохая. Остальное зависит от тебя.

Удачи вам!

+0

Спасибо! Я действительно хочу понять код сейчас, а затем попробовать. Есть ли хорошее руководство для этих инструкций? – user2696208

+1

Посетите мой блог armneon.blogspot.com В дополнение к моим собственным учебникам есть некоторые ссылки. –

+0

@ user2696208 Я сделал серьезную ошибку в неправильном толковании вашего кода. Я обновляю свой ответ с «пересмотренной» версией. –

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