Re: [PATCH] x86: Align jump targets to 1 byte boundaries

Linus Torvalds
2015-04-10T18:48:35Z

On Fri, Apr 10, 2015 at 5:50 AM, Denys Vlasenko <dvlasenk@redhat.com> 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.

HOWEVER.

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.

Linus

---
struct dummy {
unsigned long a, b, c;
};

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