optimisation: changed some for() loops to do-while() to give the compiler

a hint that there has to be at least one iteration.
This commit is contained in:
Jean-Marc Valin 2008-03-26 21:31:56 +11:00
parent df7ab43087
commit fed97d58b5
3 changed files with 13 additions and 9 deletions

View file

@ -1,4 +1,4 @@
/* (C) 2007 Jean-Marc Valin, CSIRO /* (C) 2007-2008 Jean-Marc Valin, CSIRO
*/ */
/* /*
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -165,6 +165,7 @@ static int bits2pulses(const CELTMode *m, int band, int bits)
for (i=0;i<LOG_MAX_PULSES;i++) for (i=0;i<LOG_MAX_PULSES;i++)
{ {
int mid = (lo+hi)>>1; int mid = (lo+hi)>>1;
/* OPT: Make sure this is implemented with a conditional move */
if (m->bits[band][mid] >= bits) if (m->bits[band][mid] >= bits)
hi = mid; hi = mid;
else else

View file

@ -1,4 +1,4 @@
/* (C) 2007 Jean-Marc Valin, CSIRO /* (C) 2007-2008 Jean-Marc Valin, CSIRO
*/ */
/* /*
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View file

@ -157,8 +157,9 @@ void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, const celt_norm_t *
/* Choose between fast and accurate strategy depending on where we are in the search */ /* Choose between fast and accurate strategy depending on where we are in the search */
if (pulsesLeft>1) if (pulsesLeft>1)
{ {
for (j=0;j<N;j++) /* OPT: This loop is very CPU-intensive */
{ j=0;
do {
celt_word32_t num; celt_word32_t num;
celt_word16_t den; celt_word16_t den;
/* Select sign based on X[j] alone */ /* Select sign based on X[j] alone */
@ -173,13 +174,14 @@ void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, const celt_norm_t *
den = ROUND16(Ryy,14); den = ROUND16(Ryy,14);
/* The idea is to check for num/den >= best_num/best_den, but that way /* The idea is to check for num/den >= best_num/best_den, but that way
we can do it without any division */ we can do it without any division */
/* OPT: Make sure to use a conditional move here */
if (MULT16_32_Q15(best_den, num) > MULT16_32_Q15(den, best_num)) if (MULT16_32_Q15(best_den, num) > MULT16_32_Q15(den, best_num))
{ {
best_den = den; best_den = den;
best_num = num; best_num = num;
best_id = j; best_id = j;
} }
} } while (++j<N); /* Promises we loop at least once */
} else { } else {
for (j=0;j<N;j++) for (j=0;j<N;j++)
{ {
@ -275,17 +277,18 @@ void intra_prediction(celt_norm_t *x, celt_mask_t *W, int N, int K, celt_norm_t
celt_word32_t xy=0, yy=0; celt_word32_t xy=0, yy=0;
celt_word32_t num; celt_word32_t num;
celt_word16_t den; celt_word16_t den;
/* If this doesn't generate a double-MAC on supported architectures, /* OPT: If this doesn't generate a double-MAC (on supported architectures),
complain to your compilor vendor */ complain to your compilor vendor */
for (j=0;j<N;j++) j=0;
{ do {
xy = MAC16_16(xy, x[j], Y[i+N-j-1]); xy = MAC16_16(xy, x[j], Y[i+N-j-1]);
yy = MAC16_16(yy, Y[i+N-j-1], Y[i+N-j-1]); yy = MAC16_16(yy, Y[i+N-j-1], Y[i+N-j-1]);
} } while (++j<N); /* Promises we loop at least once */
/* Using xy^2/yy as the score but without having to do the division */ /* Using xy^2/yy as the score but without having to do the division */
num = MULT16_16(ROUND16(xy,14),ROUND16(xy,14)); num = MULT16_16(ROUND16(xy,14),ROUND16(xy,14));
den = ROUND16(yy,14); den = ROUND16(yy,14);
/* If you're really desperate for speed, just use xy as the score */ /* If you're really desperate for speed, just use xy as the score */
/* OPT: Make sure to use a conditional move here */
if (MULT16_32_Q15(best_den, num) > MULT16_32_Q15(den, best_num)) if (MULT16_32_Q15(best_den, num) > MULT16_32_Q15(den, best_num))
{ {
best_num = num; best_num = num;