QT는 임베디드에서 개느리다.
실제적으로 성능이 대폭적으로 향상되거나 하진 않는다.
눈알 빠지게 추적하다가 찾아낸 바틀넥 위치를 조지다가
일단 범인은 잡았고 검색 때려서 나보다 먼저 시도한 고마운 분을 찾았다.
물론 여기만 최적화 할 건 아니고.
void qt_memfill32_arm(quint32 *dest, quint32 value, int count)
{
asm __volatile__(
"mov r3, %[value]\n\t"
"mov r4, %[value]\n\t"
"mov r5, %[value]\n\t"
"mov r6, %[value]\n\t"
"mov r7, %[value]\n\t"
"mov r8, %[value]\n\t"
"mov r9, %[value]\n"
"mfill_loop:\n\t"
"subs %[count], %[count], #32\n\t"
"stmgeia %[dest]!, {%[value], r3, r4, r5, r6, r7, r8, r9}\n\t"
"stmgeia %[dest]!, {%[value], r3, r4, r5, r6, r7, r8, r9}\n\t"
"stmgeia %[dest]!, {%[value], r3, r4, r5, r6, r7, r8, r9}\n\t"
"stmgeia %[dest]!, {%[value], r3, r4, r5, r6, r7, r8, r9}\n\t"
"bgt mfill_loop\n"
"mfill_remaining:\n\t"
"@ Fill up to 31 remaining pixels\n\t"
"@ Fill 16 pixels\n\t"
"tst %[count], #16\n\t"
"stmneia %[dest]!, {%[value], r3, r4, r5, r6, r7, r8, r9}\n\t"
"stmneia %[dest]!, {%[value], r3, r4, r5, r6, r7, r8, r9}\n\t"
"@ Fill 8 pixels\n\t"
"tst %[count], #8\n\t"
"stmneia %[dest]!, {%[value], r3, r4, r5, r6, r7, r8, r9}\n\t"
"@ Fill 4 pixels\n\t"
"tst %[count], #4\n\t"
"stmneia %[dest]!, {%[value], r3, r4, r5}\n\t"
"@ Fill 2 pixels\n\t"
"tst %[count], #2\n\t"
"stmneia %[dest]!, {%[value], r3}\n\t"
"@ Fill last one\n\t"
"tst %[count], #1\n\t"
"strne %[value], [%[dest]]\n\t"
: "=r" (dest), "=r" (count)
: [dest] "r" (dest), [value] "r" (value), [count] "r" (count)
: "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r9", "cc"
);
}
아이디어는 늘 그렇듯이.
루프 깨고 가용 레지스터 총출동.
아.. 숙취에 이게 뭔 병신짓이냐..