From b7274996bce46a1d2542b890b37f2f49299ee17c Mon Sep 17 00:00:00 2001 From: Daniel Sebastian Date: Tue, 16 Jun 2015 10:38:56 -0400 Subject: [PATCH 1/2] Optimize p_box3x3_f32 function Signed-off-by: Daniel Sebastian --- src/image/p_box3x3.c | 104 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 83 insertions(+), 21 deletions(-) diff --git a/src/image/p_box3x3.c b/src/image/p_box3x3.c index 746d21f..f348f86 100644 --- a/src/image/p_box3x3.c +++ b/src/image/p_box3x3.c @@ -21,35 +21,97 @@ void p_box3x3_f32(const float *x, float *r, int rows, int cols) { - int ia, ja; - float E; + int i, j; + float sum; const float *px; float *pr; px = x; pr = r; - for (ia = 1; ia <= (rows - 2); ia++) { - for (ja = 1; ja <= (cols - 2); ja++) { - E = 0; - E += (*px++); - E += (*px++); - E += (*px++); - px += cols - 3; - E += (*px++); - E += (*px++); - E += (*px++); - px += cols - 3; - E += (*px++); - E += (*px++); - E += (*px++); - px += cols - 3; - *pr = E * M_DIV9; - px += 1 - 3 * cols; // advance mask matrix in one column. + // Process first row + + // Calculate the first sum + sum = (*px) + (*(px+1)) + (*(px+2)); + // The sums from the first row are only used for a single row of the output. + *pr = sum; + pr++; + for (j = 3; j < cols; j++) { + // All subsequent sums are calculated by removing the leftmost + // value, and adding the next. + sum += (*(px+3)) - (*px); + *pr = sum; + px++; + pr++; + } + px += 3; // Advance input pointer to beginning of next row. + pr = r; + + // Process second row + + sum = (*px) + (*(px+1)) + (*(px+2)); + // The second row's sums are added to the first row's, and used to + // initialize a new output row. + *pr += sum; + *(pr+cols-2) = sum; + pr++; + for (j = 3; j < cols; j++) { + sum += (*(px+3)) - (*px); + *pr += sum; + *(pr+cols-2) = sum; + px++; + pr++; + } + px += 3; // Advance input pointer to beginning of next row. + + // Process (rows - 4) middle rows + + for (i = 4; i < rows; i++) { + // These rows are the final inclusion to the output row from two + // iterations ago (so the final division is applied). They are also + // added to the previous row's output and used to initialize the + // next row. + sum = (*px) + (*(px+1)) + (*(px+2)); + *(pr-cols+2) = (*(pr-cols+2) + sum) * M_DIV9; + *pr += sum; + *(pr+cols-2) = sum; + pr++; + for (j = 3; j < cols; j++) { + sum += (*(px+3)) - (*px); + *(pr-cols+2) = (*(pr-cols+2) + sum) * M_DIV9; + *pr += sum; + *(pr+cols-2) = sum; + px++; pr++; } - px = px + 2; // advance pointer to the beginning of next row. + px += 3; // Advance input pointer to beginning of next row. + } + + // Process second-to-last row + + sum = (*px) + (*(px+1)) + (*(px+2)); + *(pr-cols+2) = (*(pr-cols+2) + sum) * M_DIV9; + *pr += sum; + pr++; + for (j = 3; j < cols; j++) { + sum += (*(px+3)) - (*px); + *(pr-cols+2) = (*(pr-cols+2) + sum) * M_DIV9; + *pr += sum; + px++; + pr++; } + px += 3; // Advance input pointer to beginning of next row. + pr -= cols-2; // Reset output pointer to the previous row. + + // Process last row - return; + sum = (*px) + (*(px+1)) + (*(px+2)); + *pr = (*(pr) + sum) * M_DIV9; + pr++; + for (j = 3; j < cols; j++) { + sum += (*(px+3)) - (*px); + *pr = (*(pr) + sum) * M_DIV9; + px++; + pr++; + } } From d6caaa3aa6d643ed07ff26e6735b3f68647a8509 Mon Sep 17 00:00:00 2001 From: Daniel Sebastian Date: Wed, 17 Jun 2015 22:32:39 -0400 Subject: [PATCH 2/2] image: p_box3x3_f32: Rewitten for less verbosity The new version is mostly the same, with the four outer loops (which handled the first and last rows) now integrated into the center loop, using 'if' statements rather than separate loops to get the desired behavioral changes for the outer rows. Signed-off-by: Daniel Sebastian --- src/image/p_box3x3.c | 108 +++++++++++++------------------------------ 1 file changed, 31 insertions(+), 77 deletions(-) diff --git a/src/image/p_box3x3.c b/src/image/p_box3x3.c index f348f86..f70a649 100644 --- a/src/image/p_box3x3.c +++ b/src/image/p_box3x3.c @@ -27,91 +27,45 @@ void p_box3x3_f32(const float *x, float *r, int rows, int cols) float *pr; px = x; - pr = r; + // Initialize the output pointer to the (-1, 0) coordinate + pr = r - cols + 2; - // Process first row - - // Calculate the first sum - sum = (*px) + (*(px+1)) + (*(px+2)); - // The sums from the first row are only used for a single row of the output. - *pr = sum; - pr++; - for (j = 3; j < cols; j++) { - // All subsequent sums are calculated by removing the leftmost - // value, and adding the next. - sum += (*(px+3)) - (*px); - *pr = sum; - px++; - pr++; - } - px += 3; // Advance input pointer to beginning of next row. - pr = r; - - // Process second row - - sum = (*px) + (*(px+1)) + (*(px+2)); - // The second row's sums are added to the first row's, and used to - // initialize a new output row. - *pr += sum; - *(pr+cols-2) = sum; - pr++; - for (j = 3; j < cols; j++) { - sum += (*(px+3)) - (*px); - *pr += sum; - *(pr+cols-2) = sum; - px++; - pr++; - } - px += 3; // Advance input pointer to beginning of next row. - - // Process (rows - 4) middle rows - - for (i = 4; i < rows; i++) { - // These rows are the final inclusion to the output row from two - // iterations ago (so the final division is applied). They are also - // added to the previous row's output and used to initialize the - // next row. + for (i = 0; i < rows; i++) { + // The first sum is calculated directly. sum = (*px) + (*(px+1)) + (*(px+2)); - *(pr-cols+2) = (*(pr-cols+2) + sum) * M_DIV9; - *pr += sum; - *(pr+cols-2) = sum; - pr++; - for (j = 3; j < cols; j++) { - sum += (*(px+3)) - (*px); + if (i >= 2) { + // The first two input rows do not correspond to the bottom of any + // pixel filter, so skip this logic for those rows. *(pr-cols+2) = (*(pr-cols+2) + sum) * M_DIV9; + } + if (i != 0 && i != rows-1) { + // The first and last input rows do not correspond to the middle + // of any pixel filter, so skip this logic for those rows. *pr += sum; + } + if (i < rows - 2) { + // The last two input rows do not correspond to the top of any + // pixel filter, so skip this logic for those rows. *(pr+cols-2) = sum; + } + pr++; + for (j = 3; j < cols; j++) { + // All subsequent sums (in the same row) are calculated by + // removing the leftmost value, and adding the value to the + // immediate right of the currently included values. + sum += (*(px+3)) - (*px); + if (i >= 2) { + *(pr-cols+2) = (*(pr-cols+2) + sum) * M_DIV9; + } + if (i != 0 && i != rows-1) { + *pr += sum; + } + if (i < rows - 2) { + *(pr+cols-2) = sum; + } px++; pr++; } px += 3; // Advance input pointer to beginning of next row. } - - // Process second-to-last row - - sum = (*px) + (*(px+1)) + (*(px+2)); - *(pr-cols+2) = (*(pr-cols+2) + sum) * M_DIV9; - *pr += sum; - pr++; - for (j = 3; j < cols; j++) { - sum += (*(px+3)) - (*px); - *(pr-cols+2) = (*(pr-cols+2) + sum) * M_DIV9; - *pr += sum; - px++; - pr++; - } - px += 3; // Advance input pointer to beginning of next row. - pr -= cols-2; // Reset output pointer to the previous row. - - // Process last row - - sum = (*px) + (*(px+1)) + (*(px+2)); - *pr = (*(pr) + sum) * M_DIV9; - pr++; - for (j = 3; j < cols; j++) { - sum += (*(px+3)) - (*px); - *pr = (*(pr) + sum) * M_DIV9; - px++; - pr++; - } }