Re: Fixed point cairo.. or no cairo?



Behdad Esfahbod wrote:
> Instead, I suggest one implements
> an opaque matrix type for cairo's internal use that maintains properties
> like the one you suggest and short-circuits operation based on the
> properties.  These can be implemented as inlined wrappers around
> cairo_matrix_t, such that the compiler has the opportunity to optimize
> away some stuff for the constant values.
>   
That would be an improvement on ARM, but on x86 branching costs more
than doing the math and simple inlining will perform better:

Athlon XP
aivarsk benq ~/dev/poo $ ./cycles
branching:              24 cycles
function call:          698 cycles
inline multiply:        15 cycles

Mobile AMD Sempron
aivarsk cartman ~ $ ./cycles
branching:              36 cycles
function call:          648 cycles
inline multiply:        29 cycles

So if we want cairo to perform well on both, we need 2 different
implementations. Or maybe fixed-point matrix type for internal use.


P.S. Does anyone know if it's possible to inline __adddf3() and
__muldf3() when compiling with -msoft-float ? It might be that function
call overhead is the bottleneck and most problems can be solved by
compiler flags.

-- 
Aivars

#include <stdio.h>

typedef struct _cairo_matrix {
    double xx; double yx;
    double xy; double yy;
    double x0; double y0;
} cairo_matrix_t;

void
cairo_matrix_transform_distance (const cairo_matrix_t *matrix, double *dx, double *dy)
{
    double new_x, new_y;

    new_x = (matrix->xx * *dx + matrix->xy * *dy);
    new_y = (matrix->yx * *dx + matrix->yy * *dy);

    *dx = new_x;
    *dy = new_y;
}

int
main()
{
    long long start, end;
    cairo_matrix_t m = { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 };
    double x = 3.0, y = 4.0;
    double tmpx;
    int identity = 1;

    asm(".byte 0x0f, 0x31" : "=A" (start));
    if (!identity) {
        cairo_matrix_transform_distance (&m, &x, &y);
    }
    asm(".byte 0x0f, 0x31" : "=A" (end));
    printf("branching:\t\t%llu cycles\n", end - start);

    asm(".byte 0x0f, 0x31" : "=A" (start));
    cairo_matrix_transform_distance (&m, &x, &y);
    asm(".byte 0x0f, 0x31" : "=A" (end));
    printf("function call:\t\t%llu cycles\n", end - start);

    asm(".byte 0x0f, 0x31" : "=A" (start));
    tmpx = x;
    x = (m.xx * tmpx + m.xy * y);
    y = (m.yx * tmpx + m.yy * y);
    asm(".byte 0x0f, 0x31" : "=A" (end));
    printf("inline multiply:\t%llu cycles\n", end - start);

    return 0;
}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]