[PATCHSET] Multithread-safe FreeType

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCHSET] Multithread-safe FreeType

Behdad Esfahbod-3
Hi,

Over the past couple of days I developed a tool for testing FreeType in
multi-threaded environments:

  https://github.com/behdad/ftthread

and a patchset to go with it:

  https://github.com/behdad/freetype/commits/ftthread

With the patchset the test has been running happily for hours, using tens of
threads...

The patchset mainly removes use of singleton buffers in favor of stack or
per-face allocated ones.  In all cases this has no down side.  The exception
is the patch that affects the autohinter, which results in significant (~20%)
slowdown.  I plan to track that down and fix, but believe that the patchset
should be integrated before that.

Some dead code is removed as well.

Here's what https://github.com/behdad/ftthread/blob/master/README currently says:


ftthread
========

This is a test tool to use FreeType2 in a multi-threaded environment.

FreeType2 is not thread-safe, and the original author(s) of FreeType
suggest that one FT_Library per thread should be used.  Unfortunately
this is too inflexible to be really useful.

However, there are ways to use it safely in a multi-threaded environment
with simple modifications to FreeType.  I have now produced a complete
patchset to that effect and tested it using this utility.  The patchset
is available here:

  https://github.com/behdad/freetype/commits/ftthread

and I hope it to be integrated into upstream FreeType very soon.  In
the mean time, here's the new threadsafety model, which needs to be
integrated into FreeType documentation.  Note that cairo graphics
library already uses FreeType in this way and as such the entire GNOME
desktop has been relying on this model, to huge disappointment as seen
in the following bug reports, each of which have many duplicates:

  https://bugzilla.redhat.com/show_bug.cgi?id=678397
  https://bugzilla.redhat.com/show_bug.cgi?id=1004315
  https://bugzilla.redhat.com/show_bug.cgi?id=1164941
  https://bugzilla.redhat.com/show_bug.cgi?id=1165471
  https://bugs.freedesktop.org/show_bug.cgi?id=69034


Threadsafety model
==================

  - A FT_Face object can only be safely used from one thread at a time.

  - A FT_Library object can be used without modification from multiple
    threads at the same time.

  - FT_Face creation / destruction with the same FT_Library object can
    only be done from one thread at a time.


Discussion
==========

In this model, one can use a single FT_Library object across threads as
long as a mutex lock is used around FT_New_Face / FT_Done_Face.  Any calls
to FT_Load_Glyph and similar API are safe and do not need the lock to be
held as long as the same FT_Face is not used from multiple threads at the
same time.

Note that this goes almost all the way to making FreeType API useful from
multiple threads.  The only remaining bit is the unfortunately API that is
FT_Library_SetLcdFilter (and to less extent FT_Library_SetLcdFilterWeights).

I will try to work out a solution for replacing FT_Library_SetLcdFilter
using new FT_LOAD_* values.  There seem to be quite a few bits available in
that space, so that work should happen soon.


Running
=======

To run this test, give it a font file, and optionally:

  - Number of threads
  - Number of iterations per thread
  - Pixels per EM
  - Load flags in hexadecimal

The tool then will create one FT_Library, spawn many threads, and within
each thread create an FT_Face (after proper locking) and load glyphs from
the font for specified number of iterations and then destruct the face and
return.  The test also destructs and reconstructs the face every 1000
iterations.

Run with no arguments to get usage info.  Quoting here:

usage: ftthread fontfile.ttf [numthreads] [numiters] [ppem] [loadflags-hex]

numthreads, numiters, and ppem default to 100.

loadflags defaults to 0.  Values are in hex.
Useful flags to logically or:
NO_HINTING=2
RENDER=4
FORCE_AUTOHINT=20
MONOCHROME=1000
NO_AUTOHINT=8000
COLOR=100000


In particular, I've found the following load_flags values to be useful:

  0 Use native hinting (bytecode / CFF), no rasterization
  2 No hinting whatsoever
  20 Use autohinter
  4 Rasterize using smooth rasterizer
  1004 Rasterize using monochrome rasterizer

Remember to test with both TrueType and CFF fonts.  I have done both.
I have not tested bitmap (color or not) fonts, but don't know of any
outstanding issues there.

For example, here's how I test rasterizing glyphs in Roboto-Regular.ttf
using 40 threads, 10000 iterations per thread, at 150ppm, and repeat
that until it fails:

$ time while ./ftthread Roboto-Regular.ttf 40 10000 150 4; do echo -n '.'; done

Make sure you run "ulimit -c unlimited" in your shell first such that
you get a core dump when the test fails.

Please report any failures you discover if it happens with a FreeType
including the patchset.


Thanks!

Behdad Esfahbod
30 December 2014
_______________________________________________
gtk-i18n-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-i18n-list
Reply | Threaded
Open this post in threaded view
|

Re: [PATCHSET] Multithread-safe FreeType

Behdad Esfahbod-3
On 14-12-30 04:06 PM, Behdad Esfahbod wrote:
> The patchset mainly removes use of singleton buffers in favor of stack or
> per-face allocated ones.  In all cases this has no down side.  The exception
> is the patch that affects the autohinter, which results in significant (~20%)
> slowdown.  I plan to track that down and fix, but believe that the patchset
> should be integrated before that.

The slowdown was more like 60%.  I've already found the root cause and am
working on a fix.

--
behdad
http://behdad.org/
_______________________________________________
gtk-i18n-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-i18n-list
Reply | Threaded
Open this post in threaded view
|

Re: [ft-devel] [PATCHSET] Multithread-safe FreeType

Werner LEMBERG
In reply to this post by Behdad Esfahbod-3

> The patchset mainly removes use of singleton buffers in favor of
> stack or per-face allocated ones.  In all cases this has no down
> side.  [...]

Thanks!  I'll have a look next year :-) Just wondering: How much does
your patch increase FreeType's memory footprint?  What's the behaviour
in tight memory situations?  In particular, there are still a lot of
programs that don't need thread safety at all, and for such systems I
would like to avoid any bloated memory consumptions.


    Werner


PS: In general, I would like to test FreeType in situations where the
    available memory is largely reduced so that I intentionally get
    many allocation errors.  Is there a GNU/Linux tool to restrict the
    available memory of a process or program?
_______________________________________________
gtk-i18n-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-i18n-list
Reply | Threaded
Open this post in threaded view
|

Re: [ft-devel] [PATCHSET] Multithread-safe FreeType

Behdad Esfahbod-3
On 14-12-30 10:25 PM, Werner LEMBERG wrote:
>
>> The patchset mainly removes use of singleton buffers in favor of
>> stack or per-face allocated ones.  In all cases this has no down
>> side.  [...]
>
> Thanks!  I'll have a look next year :-)

I've now pushed many more commits out, that fix a couple of invalid memory
accesses, as well as fixing up allocations such that there is no performance
hit whatsoever caused by this branch.  If anything, it should speed things up
a bit.


> Just wondering: How much does
> your patch increase FreeType's memory footprint?

In all cases it should make FreeType allocate and hold onto *less* memory.
The stack consumption has gone up about 20kb (about FT_RENDER_POOL_SIZE +
2kb).  There's one exception, which is the bytecode execution context.  We now
allocate one of that per face on demand.  It's 1kb only.


>  What's the behaviour in tight memory situations?

Should be improved.  Instead of relying on allocated memory, many places now
use stack memory.


>  In particular, there are still a lot of
> programs that don't need thread safety at all, and for such systems I
> would like to avoid any bloated memory consumptions.

The whole thing streamlines a lot of memory allocations, resulting in fewer
allocations in all cases.


>     Werner
>
>
> PS: In general, I would like to test FreeType in situations where the
>     available memory is largely reduced so that I intentionally get
>     many allocation errors.  Is there a GNU/Linux tool to restrict the
>     available memory of a process or program?

I know both dbus and cairo had tools to do this, but can't find either.


--
behdad
http://behdad.org/
_______________________________________________
gtk-i18n-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-i18n-list
Reply | Threaded
Open this post in threaded view
|

Re: [ft-devel] [PATCHSET] Multithread-safe FreeType

Behdad Esfahbod-3
On 15-01-03 09:16 PM, Behdad Esfahbod wrote:

> On 14-12-30 10:25 PM, Werner LEMBERG wrote:
>> >
>>> >> The patchset mainly removes use of singleton buffers in favor of
>>> >> stack or per-face allocated ones.  In all cases this has no down
>>> >> side.  [...]
>> >
>> > Thanks!  I'll have a look next year :-)
> I've now pushed many more commits out, that fix a couple of invalid memory
> accesses, as well as fixing up allocations such that there is no performance
> hit whatsoever caused by this branch.  If anything, it should speed things up
> a bit.

I'm wondering: did anyone got the chance to try this branch out?

Cheers,
--
behdad
http://behdad.org/
_______________________________________________
gtk-i18n-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-i18n-list
Reply | Threaded
Open this post in threaded view
|

Re: [ft-devel] [PATCHSET] Multithread-safe FreeType

Werner LEMBERG

> I'm wondering: did anyone got the chance to try this branch out?

Not yet.  Still working on a new ttfautohint release.


    Werner
_______________________________________________
gtk-i18n-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-i18n-list
Reply | Threaded
Open this post in threaded view
|

Re: [ft-devel] [PATCHSET] Multithread-safe FreeType

Werner LEMBERG
In reply to this post by Behdad Esfahbod-3

> Over the past couple of days I developed a tool for testing FreeType in
> multi-threaded environments:
>
>   https://github.com/behdad/ftthread
>
> and a patchset to go with it:
>
>   https://github.com/behdad/freetype/commits/ftthread

Your patches are now in FreeType's git repository.  Thanks a lot!


    Werner
_______________________________________________
gtk-i18n-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-i18n-list