for scalar==float, tis faster to always to MIN and MAX, than to put an ELSE

betwixt them.

    if (x < min) min = x; else if (x > max) max = x;

This expression forces the compiler to know if the min expression executed, and
insert a conditional jump before the max. Slow.

    if (x < min) min = x; if (x > max) max = x;

This version allows the compiler to emitt MINSS and MAXSS unconditionally, giving
us a loop with zero branches inside.



git-svn-id: http://skia.googlecode.com/svn/trunk@3939 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
reed@google.com 2012-05-15 15:12:29 +00:00
parent a2b793c4d1
commit 921374d4cc

View File

@ -61,6 +61,15 @@ void SkRect::toQuad(SkPoint quad[4]) const {
#define SkFLOATCODE(code)
#endif
// For float compares (at least on x86, by removing the else from the min/max
// computation, we get MAXSS and MINSS instructions, and no branches.
// Fixed point has no such opportunity (afaik), so we leave the else in that case
#ifdef SK_SCALAR_IS_FLOAT
#define MINMAX_ELSE
#else
#define MINMAX_ELSE else
#endif
void SkRect::set(const SkPoint pts[], int count) {
SkASSERT((pts && count > 0) || count == 0);
@ -94,6 +103,7 @@ void SkRect::set(const SkPoint pts[], int count) {
// If all of the points are finite, accum should stay 0. If we encounter
// a NaN or infinity, then accum should become NaN.
SkFLOATCODE(float accum = 0;)
SkFLOATCODE(accum *= l; accum *= t;)
for (int i = 1; i < count; i++) {
SkScalar x = pts[i].fX;
@ -101,8 +111,8 @@ void SkRect::set(const SkPoint pts[], int count) {
SkFLOATCODE(accum *= x; accum *= y;)
if (x < l) l = x; else if (x > r) r = x;
if (y < t) t = y; else if (y > b) b = y;
if (x < l) l = x; MINMAX_ELSE if (x > r) r = x;
if (y < t) t = y; MINMAX_ELSE if (y > b) b = y;
}
#ifdef SK_SCALAR_IS_FLOAT