back

by claytonwramsey·2y ago·view on hn ↗
That's very interesting to me - I had seen the `[unknown]` mountain in my profiles but never knew why. I think it's a tough thing to justify: 2% performance is actually a pretty big difference.

It would be really nice to have fine-grained control over frame pointer inclusion: provided fine-grained profiling, we could determine whether we needed the frame pointers for a given function or compilation unit. I wouldn't be surprised if we see that only a handful of operations are dramatically slowed by frame pointer inclusion while the rest don't really care.

5 comments
> 2% performance is actually a pretty big difference.

No it's not, particularly when it can help you identify hotspots via profiling that can net you improvements of 10% or more.

Sure, but how many of the people running distro compiled code do perf analysis? And how many of the people who need to do perf analysis are unable to use a with-frame-pointers version when they need to? And how many of those 10% perf improvements are in common distro code that get upstreamed to improve general user experience, as opposed to being in private application code?

If you're netflix then "enable frame pointers" is a no-brainer. But if you're a distro who's building code for millions of users, many of whom will likely never need to fire up a profiler, I think the question is at least a little trickier. The overall best tradeoff might end up being still to enable frame pointers, but I can see the other side too.

It's not a technical tradeoff, it's a refusal to compromise. Lack of frame pointers prevents many groups from using software built by distros altogether. If a distro decides that they'd rather make things go 1% faster for grandma, at the cost of alienating thousands of engineers at places like Netflix and Google who simply want to volunteer millions of dollars of their employers resources helping distros to find 10x performance improvements, then the distros are doing a great disservice to both grandma and themselves.
I mean if you need to do performance analysis on a software just recompile it. Why it's such a big deal?

In the end a 2% of performance of every application it's a big deal. On a single computer may not be that significant, think about all the computers, servers, clusters, that run a Linux distro. And yes, I would ask a Google engineer that if scaled on the I don't know how many servers and computers that Google has a 2% increase in CPU usage is not a big deal: we are probably talking about hundreds of kW more of energy consumption!

We talk a lot of energy efficiency these days, to me wasting a 2% only to make the performance analysis of some software easier (that is that you can analyze directly the package shipped by the distro and you don't have to recompile it) it's something stupid.

The average European home consumes 400 watts at any given moment. Modern digital smart meters can consume 4 watts on average, which is 1% of a household's power consumption. On the grand scheme of society, these 1% losses in each home add up. If we consider all the grid monitoring equipment that's typically employed by electrical companies outside the home, the problem becomes much greater. In order to maximize energy efficiency and improve our environmental footprint, we must remove these metering and monitoring devices, which don't actually contribute to the delivery and consumption of power.
> I mean if you need to do performance analysis on a software just recompile it. Why it's such a big deal?

Not having them enabled on all dependencies makes them significantly less useful if your application interacts with the system in a meaningful way. "Just recompile" (glibc + xorg + qt + whatever else you use) is a very hefty thing.

Having them enabled by default also enables devs to ask their users for traces. I can reasonably tell someone to install sysprof or something, click a few buttons and send me a trace. I cannot reasonably tell them to compile the project (+ dependencies). And tbh, even devs cba if they have to jump through too many hoops.

> We talk a lot of energy efficiency these days, to me wasting a 2% only to make the performance analysis of some software easier (that is that you can analyze directly the package shipped by the distro and you don't have to recompile it) it's something stupid.

We're trading all kinds of efficiencies for all kinds of niche benefits all the time. This enables analysis of what is shipped in real use across the whole stack with the alternative being much less useful or a lot more (human) work. To me it's worth 2% and I'm shocked (well... not really) it's not for more people.

Presenting people with false dichotomies is no way to build something worthwhile
I would say the question here is what should be the default, and that the answer is clearly "frame pointers", from my point of view.

Code eking out every possible cycle of performance can enable a no-frame-pointer optimization and see if it helps. But it's a bad default for libc, and for the kernel.

You can turn it on/off per function by attaching one of these GCC attribute to the function declaration (although it doesn't work on LLVM):

  __attribute__((optimize("no-omit-frame-pointer")))
  __attribute__((optimize("omit-frame-pointer")))
The optimize fn attr causes other unintended side effects. Its usage is banned on the Linux kernel.
The performance cost in your case may be much smaller than 2 per cent.

Don't completely trust the benchmarks on this; they are a bit synthetic and real-world applications tend to produce very different results.

Plus, profiling is important. I was able to speed up various segments of my code by up to 20 per cent by profiling them carefully.

And, at the end of the day, if your application is so sensitive about any loss of performance, you can simply profile your code in your lab using frame pointers, then omit them in the version released to your customers.

> And, at the end of the day, if your application is so sensitive about any loss of performance, you can simply profile your code in your lab using frame pointers, then omit them in the version released to your customers.

That is what should be done but TFA is about distros shipping code with frame pointers to end uses because some developers are too lazy to recompile libc when profiling. Somehow shipping different copies of libc, one indended for end users on low-powered devices and one indended for developers is not even considered.

If you can't introspect the release version of your software, you have no way of determining what the issue is. You're doing psuedo-science and guesswork to try and replicate the issue on a development version of the software. And if you put in a few new logging statements into the release version, there's a pretty good chance that simply restarting the software will cause the symptom to go away.
The measured overhead is slightly less than 1%. There have been some rare historical cases where frame pointers have caused performance to blow up but those are fixed.
It’s usually a lot less than 2%.