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 циклов/итерация не плохая. Остальное зависит от тебя.
Удачи вам!
Я не прошу кода, я просто пытаюсь понять, есть ли способ оптимизировать исходный код через NEON. Поскольку я не эксперт NEON, я даже не знаю, может ли то, что я прошу, это возможно. Если это так, я собираюсь реализовать его сам. Мне нужен только общий совет по поводу осуществимости. – user2696208
Без контекстного/компилируемого кода, единственное, что я могу предложить на этом этапе, - это _hint_ компилятору, что это должно быть векторизовано/будет полезно для векторизации. См. Http://stackoverflow.com/questions/14256156/how-to-give-hint-to-gcc-about-loop-count для параметров. –
Я отредактировал ответ, добавив больше контекста. – user2696208