아래 코드는 객체 감지 프로그램에서 집중적으로 호출되며 실행 시간은 약 80 %입니다. 상당히 속도를 높이는 방법이 있습니까? CPU에서 LBP를 계산하기 위해 아래의 코드를 빠르게하는 방법은 무엇입니까?
#define CALC_SUM_(p0, p1, p2, p3, offset) ((p0)[offset] - (p1)[offset] - (p2)[offset] + (p3)[offset])
inline int calc_lbp2(float *p[], int offset)
{
int cval = CALC_SUM_(p[5], p[6], p[9], p[10], offset);
return (CALC_SUM_(p[0], p[1], p[4], p[5], offset) >= cval ? 128 : 0) | // 0
(CALC_SUM_(p[1], p[2], p[5], p[6], offset) >= cval ? 64 : 0) | // 1
(CALC_SUM_(p[2], p[3], p[6], p[7], offset) >= cval ? 32 : 0) | // 2
(CALC_SUM_(p[6], p[7], p[10], p[11], offset) >= cval ? 16 : 0) | // 5
(CALC_SUM_(p[10], p[11], p[14], p[15], offset) >= cval ? 8 : 0)| // 8
(CALC_SUM_(p[9], p[10], p[13], p[14], offset) >= cval ? 4 : 0)| // 7
(CALC_SUM_(p[8], p[9], p[12], p[13], offset) >= cval ? 2 : 0)| // 6
(CALC_SUM_(p[4], p[5], p[8], p[9], offset) >= cval ? 1 : 0);
}
나는 SSE를 시도했지만 프로그램 (원래 실행 시간은 약 170 밀리)에 대한 자세한 50ms의 비용 :
inline int calc_lbp_sse(float *p[], int offset)
{
static unsigned short bits[] = {0x0080, 0x0040, 0x0020, 0x0010, 0x0008, 0x0004, 0x0002, 0x0001};
short c = CALC_SUM_(p[5], p[6], p[9], p[10], offset);
__m128i a = _mm_setr_epi16
(
CALC_SUM_(p[0], p[1], p[4], p[5], offset),
CALC_SUM_(p[1], p[2], p[5], p[6], offset),
CALC_SUM_(p[2], p[3], p[6], p[7], offset),
CALC_SUM_(p[6], p[7], p[10], p[11], offset),
CALC_SUM_(p[10], p[11], p[14], p[15], offset),
CALC_SUM_(p[9], p[10], p[13], p[14], offset),
CALC_SUM_(p[8], p[9], p[12], p[13], offset),
CALC_SUM_(p[4], p[5], p[8], p[9], offset)
);
__m128i b = _mm_setr_epi16(c, c, c, c, c, c, c, c);
__m128i res = _mm_cmplt_epi16(b,a);
unsigned short* vals = (unsigned short*)&res;
return ((vals[0]&bits[0]) | (vals[1]&bits[1]) | (vals[2]&bits[2]) | (vals[3]&bits[3]) |
(vals[4]&bits[4]) | (vals[5]&bits[5]) |(vals[6]&bits[6]) |(vals[7]&bits[7]));
}
지금은 SSE를 사용하여 단일 위치에서 LBP 평가의 속도를 높이고 있습니다. 코드 s.t를 리팩터링하십시오. 당신은 8 또는 16 연속 픽셀에 대한 LBP를 연속적으로 평가하고 있습니다. 이것은 훨씬 잘 작동 할 수 있습니다. –
또한 LBP 평가는 본질적으로 추악한 메모리 액세스 패턴을 가지고 있으며, 특히 많은 기능과 이미지가있는 경우 캐시 미스가 많이 발생할 수 있습니다. –
모든 '...> = cval? 64 : 0' 식 표현식으로'(...> = cval) << 6'과 같은 식으로 분기를 제거 할 수 있습니까? – japreiss