ref: fed97d58b58096ccf482d8e8df875eb04439ea70
parent: df7ab43087a7713a60b8ef4721d42dec22f2a222
author: Jean-Marc Valin <[email protected]>
date: Wed Mar 26 17:31:56 EDT 2008
optimisation: changed some for() loops to do-while() to give the compiler a hint that there has to be at least one iteration.
--- a/libcelt/rate.c
+++ b/libcelt/rate.c
@@ -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
@@ -165,6 +165,7 @@
for (i=0;i<LOG_MAX_PULSES;i++)
{
int mid = (lo+hi)>>1;
+ /* OPT: Make sure this is implemented with a conditional move */
if (m->bits[band][mid] >= bits)
hi = mid;
else
--- a/libcelt/rate.h
+++ b/libcelt/rate.h
@@ -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
--- a/libcelt/vq.c
+++ b/libcelt/vq.c
@@ -157,8 +157,9 @@
/* Choose between fast and accurate strategy depending on where we are in the search */
if (pulsesLeft>1)
{
- for (j=0;j<N;j++)
- {
+ /* OPT: This loop is very CPU-intensive */
+ j=0;
+ do {
celt_word32_t num;
celt_word16_t den;
/* Select sign based on X[j] alone */
@@ -173,6 +174,7 @@
den = ROUND16(Ryy,14);
/* The idea is to check for num/den >= best_num/best_den, but that way
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))
{
best_den = den;
@@ -179,7 +181,7 @@
best_num = num;
best_id = j;
}
- }
+ } while (++j<N); /* Promises we loop at least once */
} else {
for (j=0;j<N;j++)
{
@@ -275,17 +277,18 @@
celt_word32_t xy=0, yy=0;
celt_word32_t num;
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 */
- for (j=0;j<N;j++)
- {
+ j=0;
+ do {
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]);
- }
+ } while (++j<N); /* Promises we loop at least once */
/* Using xy^2/yy as the score but without having to do the division */
num = MULT16_16(ROUND16(xy,14),ROUND16(xy,14));
den = ROUND16(yy,14);
/* 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))
{
best_num = num;