[lkml]   [2015]   [Apr]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    SubjectRe: [PATCH] x86: Align jump targets to 1 byte boundaries
    On Fri, Apr 10, 2015 at 5:50 AM, Denys Vlasenko <> wrote:
    > However, I'm an -Os guy. Expect -O2 people to disagree :)

    I used to be an -Os guy too. I'm a big believer in I$ density.


    It turns out that gcc's -Os is just horrible nasty crap. It doesn't
    actually make good tradeoffs for code density, because it doesn't make
    any tradeoffs at all. It tries to choose small code, even when it's
    ridiculously bad small code.

    For example, a 24-byte static memcpy is best done as three quad-word
    load/store pairs. That's very cheap, and not at all unreasonable.

    But what does gcc do? It does a "rep movsl".

    Seriously. That's *shit*. It absolutely kills performance on some very
    critical code.

    I'm not making that up. Try "-O2" and "-Os" on the appended trivial
    code. Yes, the "rep movsl" is smaller, but it's incredibly expensive,
    particularly if the result is partially used afterwards.

    And I'm not a hater of "rep movs" - not at all. I think that "rep
    movsb" is basically a perfect way to tell the CPU "do an optimized
    memcpy with whatever cache situation you have". So I'm a big fan of
    the string instructions, but only when appropriate. And "appropriate"
    here very much includes "I don't know the memory copy size, so I'm
    going to call out to some complex generic code that does all kinds of
    size checks and tricks".

    Replacing three pairs of "mov" instructions with a "rep movs" is insane.

    (There are a couple of other examples of that kind of issues with
    "-Os". Like using "imul $15" instead of single shift-by-4 and
    subtract. Again, the "imul" is certainly smaller, but can have quite
    bad latency and throughput issues).

    So I'm no longer a fan of -Os. It disables too many obviously good
    code optimizations.


    struct dummy {
    unsigned long a, b, c;

    void test(struct dummy *a, struct dummy *b)
    *b = *a;

     \ /
      Last update: 2015-04-10 21:21    [W:16.074 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site