331 karma · joined January 29, 2011
2) The speed and efficiency of backtrace generation can affect recovery times. It's far more than 50ms for a lot of server-side or embedded applications.
3) Large programs today cannot be debugged feasibly (as in, good luck in generating a detailed crash report, your system will likely not have the resources), especially if they're time sensitive as well (tracing is the typical approach there). There are engineers out there who have to spend hours just to extract a small memory dump from a single thread.
4) Certain classes of bugs are best observed over time and minimizing jitter is important (more on that later as we unveil some features of the advanced tracer and user interface).
Less intrusive real-time profiling is interesting to us, but currently only in the context of state leading to a fatal bug (this also includes bugs that involve hanging such as an infinite loop). The technology does have applications for performance management but this isn't something we are focusing on at the moment.
On performance: The execution speed being touted here is not that of a frame unwinder and we're building something that goes beyond this in scope. Our core client-side technology is a debugging library optimized for tracing. Unwinding was only a bottleneck for some specific ridiculous workloads and usually the bottleneck is elsewhere if program structure is being parsed (and this is where the general purpose debuggers end up taking up so much time).
There are applications out there that are so complex that traditional debuggers are simply infeasible (imagine 30 minute+ backtraces). However, what we're excited about are all those spare cycles we get to make use of...
On libunwind: Yes. We'll be targeting some exotic platforms, and this is where libunwind definitely helps. It definitely lacks in file format abstractions but we support multiple unwinding backends for this reason, it will be painful but not too painful.
Thanks for the SOSP link, looks interesting. I agree, this is an area that has definitely been neglected by academia.
We're very excited for the first release of our platform and I'll keep you posted on it, your feedback would be great and we think we've come up with very useful technology.
http://freebsd.1045724.n5.nabble.com/PATCH-BPF-Just-In-Time-...
They are stealing content.
Another user (leephillips) posted the following about their posts: "I went to the site and left a comment complaining about how they stole your article. They deleted the comment, and you still aren't credited. Does HN have a blacklist of sites that steal content or publish only blogspam? I think they should consider it." - https://news.ycombinator.com/item?id=7754641
I do question some of the results. I was disappointed with the actual lock implementations of libslock as they are anything but performant. The implementations need much more than prefetchw optimizations (many of the implementations are half as fast as they should be).
General issues: "If you don't yet have ordered atomic variables yet on your language and platform, you can emulate them by using ordinary but aligned variables whose reads and writes are guaranteed to be naturally atomic, and enforce ordering by using either platform-specific ordered API calls (such as Win32's InterlockedCompareExchange for compare-and-swap) or platform-specific explicit memory fences/barriers (for example, Linux mb)."
This is incorrect. A lot of memory models in languages provide no such guarantees, even of aligned variables (this includes C, even with volatile variables). This not only applies to regular loads/stores but even to RMW.
Produce/Consume function: We store to last->next and then to last. If we assume total store ordering, insertion itself is fine. However, it should be made clear that an explicit store fence is needed after updating the next pointer. The article gives the impression (due to statement above) that this algorithm is suitable for other languages.
In the consumer, we also need an explicit load fence. If the atomic is completely serializing, we are fine but in other languages even with aligned variables, these semantics are incorrect.
The "trim" functionality is broken as it makes no use of safe memory reclamation. It is fine to re-use nodes (assuming you don't have a concurrent lock-free traversal going on) but you need to be careful with destruction. Assume consumer is at some time T where divider != last (but divider = first). Let us say consumer is at result = divider->next->value. Pause execution of consumer after it has acquired divider->next. Producer enqueues another node and sees that first != divider (yet consumer has an earlier snapshot of divider), so it trims first. Consumer is now active again and dereferences the earlier snapshot it had of divider->next to get to value, but now this yields undefined behavior (crash or worse).
If you're looking for a learning resource, I suggest looking at http://www.rdrop.com/users/paulmck/perfbook/ and http://1024cores.net
Please make sure to navigate all the way down, before navigating to the right. Press the space bar to see the full layout of the presentation.
Did you remember to iterate vertically rather than horizontally first? It may have been you missed a lot of the content.