[cairo] Performance degradation of font cache in 1.11.3

김덕진 deokjin81.kim at samsung.com
Thu Jan 5 21:46:57 PST 2012

Hello andrea,

I'll let you know test environment, result and analysis.
1. Test environment
- Backend : image
- Tool : cairo-perf-trace
- Cairo version : 1.10.2(release version) and cairo master(6816f70da54e730e88b98c8592aa6fc84e082928)
- Test case
  TC1 : 1.10.2
  TC2 : 1.10.2 + "1"
  TC3 : 1.10.2 + "1" + "2"
  TC4 : cairo master
  TC5 : cairo master + revert "1"
  TC6 : cairo master + revert "1" + revert "2"
- I used trace file which includes so many API calls of cairo_show_glyphs().

2. Test result (median value)
Test result is average of 5 times running. Unit is second.
  TC1 : 1.2382
  TC2 : 1.2826
  TC3 : 1.2928
  TC4 : 1.3032
  TC5 : 1.2544
  TC6 : 1.2604

As you can see, TC1 and TC5 show high performance.(These TC uses font_face as key).
TC2 and TC4 show low performance. (These TC uses original_font_face as key).
In conclusion, "1" is main reason of performance degradation. And "2" is influenced performance slightly.

3. Analysis
There are 3 cases in cairo_scaled_font_create (). 
First(case1) is to use mru_scaled_font. 
Second(case2) is to use hash lookup.
Third(case3) is to create scaled_font and insert it to hash table.

In TC2 and TC4, hit ratio of _cairo_hash_table_lookup() in cairo_scaled_font_create() is lower than TC1 and TC5.
Therefore, destroy of scaled font happened more frequently.
This causes performance degradation of font cache.

Please give me feedback for this issue.
Thank you for your help.

Best Regards,
Deokjin Kim
------- Original Message -------
Sender : Andrea Canciani<ranma42 at gmail.com>
Date : 2011-12-30 20:18 (GMT+09:00)
Title : Re: [cairo] Performance degradation of font cache in 1.11.3

On Fri, Dec 30, 2011 at 10:53 AM, Deokjin Kim wrote:
> Hello all,
> When I measure elapased time of cairo using cairo-perf-trace, elapsed time of 1.10.2(release version) is shorter than that of 1.11.3(latest code). That is, performance of 1.10.2 is better than that of 1.11.3.
> I think change of font cache is playing a role in causing this issue.
> I found two root cause.
> 1. Use original_font_face instead of font_face when you create key of scaled font in cairo_scaled_font_create().
>  This change degrades hit ratio of _cairo_hash_table_lookup().
>  Below is related source code of 1.11.3.
>  1028         _cairo_scaled_font_init_key (&key, original_font_face,
>  1029                                      font_matrix, ctm, options);  // In 1.10.2, use font_face instead of original_font_face

This change happened in commit cd4b2d843b2a8c06ba78c15ff65763b5bdf54dc6
Author: Chris Wilson 
Date:   Wed Jul 13 12:33:48 2011 +0100

    scaled-font: Key the cache on the orignal font_face

    We check the incoming scaled font using the original font fce, so we
    need to also store it in the cache using the same face, and not the
    resolved font_face (which will remain the same unless the fontconfig
    configuration is updated).

    Hides the quadratic behaviour of font retrieval in recent cairo-traces.

    Signed-off-by: Chris Wilson 

AFAICT (based on the commit message) the performance of cairo-traces
should improve with it.

>  1030
>  1031         while ((scaled_font = _cairo_hash_table_lookup (font_map->hash_table,
> 2. Some change of hash table.
>  - hash: Improve double hashing
>  - hash: Compare hash values before calling keys_equal
>  - hash: Improve handling of dead entries
>  I think purpose of above code change is very good, but actual result is not good.

The performance in most practical cases should be unaffected by these changes.
In some cases (if the hash table almost fills up with dead entries) it
should be way better, as shown by the hash-table micro benchmark.

In fact I would expect the first two commits ("hash: Improve double
hashing", "hash: Compare hash values before calling keys_equal") to
have a performance impact which is basically hidden by noise.
The third commit might make the performance somewhat worse in some
cases, but it guarantees that it cannot degenerate into something
really terrible.

(It is very useful to also have the refid of commits. The above
commits are uniquely identified by
02665975d3ef0204bc512de1be55f898637f2d21 hash: Improve double hashing
400d055f3cd2eecd2cc4b91a40eac4146ec61932 hash: Compare hash values
before calling keys_equal
aaa10fbf125a80e5379172b8564384a945728cba hash: Improve handling of dead entries

> As I know, 1 is more significant than 2.
> (Actually influence of 2 is slight.)
> Please give me advice.

Could you provide some additional details about what benchmark you are
running? (what traces, backends...)

Also, could you try and give performance numbers about:
- cairo 1.10.2 (release version)
- cairo 1.10.2 (release version) + "1"
- cairo 1.10.2 (release version) + "1" + "2"

- cairo master (6816f70da54e730e88b98c8592aa6fc84e082928)
- cairo master (6816f70da54e730e88b98c8592aa6fc84e082928) + revert "1"
- cairo master (6816f70da54e730e88b98c8592aa6fc84e082928) + revert
"1" and revert "2"

This would be very useful in figuring out if (and how much) these
commits affect performance.

It should also be pointed out that there have been major changes in
the compositing architecture between 1.10 and current master, which
are likely to have a much bigger performance impact.

> Thank you in advance.

Thank you for benchmarking cairo :)


> BR,
> Deokjin Kim
> --
> cairo mailing list
> cairo at cairographics.org
> http://lists.cairographics.org/mailman/listinfo/cairo

More information about the cairo mailing list