-
Notifications
You must be signed in to change notification settings - Fork 18k
cmd/trace: view large trace all at once #11520
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
After thinking about it, the core of the trace-viewer isn't complicated, and decided to put together a quick prototype in JS: https://github.com/egonelbre/trace-spector This version can load the large file and can be improved with regards to memory usage (currently stabilizes at ~0.5GB with 1.5M events). Currently, trace-viewer AFAIK uses at least one object per event which means 1.5M objects. But I have a feeling that no matter how far we engineer it, the trace-viewer-format based solution is not going to be sufficient for Go traces. I think we should be able to do much better by pre-processing and packing. Essentially, we are hitting the browser limit rather than anything else. I think using Go + SDL/GL (whatever) would be better. I'll try to finish up the nanoseconds support in trace-viewer, I think it will be sufficient ATM. Once I have some time left over from other things I'll start on the go based trace inspector (unless someone already beats me to it). And by no means it will be as feature-complete as trace-viewer. And no promises this happening any time soon, I'm already hitting my daily limit with regards to typing too much. |
Another possibility would be to do like (say) Google maps and drop My main concern at this point, though, is to make sure that folks' Since you're versed in the guts of the trace-viewer, maybe it's worth |
The problem isn't in performance. It performs quite well. The main problem is memory usage and the way that trace events are stored in memory. LOD would be nice, but it adds a lot of machinery. Even if we implement this in trace-viewer, I'm not sure that such wide-scale change would be accepted. I'll look into whether creating a custom importer would give some improvement - but I feel it still will need to unpack into separate JavaScript objects to make it usable with trace-viewer, which essentially takes us back to the beginning.
I'm not sure how well it can be detected or on what basis it should be done. From Go side we create a limited subset of possible traces - the conditions that hold in Go may not necessarily translate to other traces e.g. Chrome, Android. Generic detection for crash would be problematic, if doable at all - hence it's not a good solution for trace-viewer. I need to inspect why exactly is it crashing at the moment and maybe it can be mitigated instead. Although with long traces we might still hit a memory limit. |
I did some further inspecting and testing. Loading the huge file works in Chrome Canary (45.0.2448.0), but still uses ~1.5GB during importing. So this seems to be a Chrome issue that has been fixed. |
That's great! Thanks, @egonelbre. I think we should leave this open, because we should probably still have a way for users to manage large traces. (Perhaps a trace from a live server or just running many benchmarks could end up needing 15GB instead of 1.5GB?) Dropping to Unplanned though. Hopefully we can do something useful for Go 1.6. There could also be third party tools to trim traces before sending them to the viewer, such as @egonelbre started. |
@egonelbre Having our own specialized viewer would be great. Then we can improve input format, make it consume less memory, improve visual appearance, improve navigation (e.g. go to a goroutine trace from full trace), fix remaining bugs (e.g. some elements don't display stack traces), etc. |
@dvyukov do you have a nice list of things that need to be visualized? Any preferences for tech used - i.e. browser vs native+gl vs native+something? I would like to make it such that it can visualize 1M events with 30FPS while streaming them in. Basically you should be able to view some portion of the trace live while program is emitting it.
Partly, yes, partly, no... I.e. someone working full time would probably get the patches, features much faster in than I. For me there's a quite large context switch to modify it and I am able, at best, to take 0.5 day from week to work on it. |
Anyways, after a bit of experimenting with gl, the cgo overhead currently is significant i.e. ~300ns per call. I wouldn't want to spend most of the CPU time for cgo. Implementing a gl command-buffer (same principle that Chromium uses) to remove the overhead would be one possibility - and something that rest of people could significantly benefit from. Whole viewer will only need simple primitives: rect, line, bezier, triangle, text, bitblt, maskblt, alphablend. Implementing such canvas in Go is mostly trivial, since content should be pixel-aligned anyways and we don't have to worry about aliasing that much (with the exception of bezier and triangle). Thoughts? |
@egonelbre I think the way to go is html+browser. There are currently no native GUI tools in std lib and no packages to do it. I feel that a native app can have more portability issues across operating systems, devices, graphics cards, etc. All current tools use html/svg+browser. |
@dvyukov you've got to start building GUI tools somewhere :). The Go canvas approach would have very few requirements - i.e. capture mouse and keyboard input and display a bitmap. But sure, I can see the reasoning and will do the HTML+browser version first. PS. do you have a nice list of things that you need to be visualized. |
@egonelbre Do you mean "logical" things (like syscall or goroutine unblocking) or "physical" things (like slice and arrow)? |
@egonelbre regarding html vs canvas, frankly I have no idea how it will look like and what consequences will be. If you want to use canvas, please ask on golang-dev. |
@dvyukov I found the logical things already from trace.go. I guess more physical things. I could write code directly for the logical things, but it becomes problematic when you want to change that format. So I think using a format for physical things would make more sense and more flexible. But I do like the compactness of current trace format. Anyways, I tried to create a protocol for it Regarding canvas vs html. The only way I can see slice/arrow rendering working is with canvas. When we get 100,000 events coming in second I would have to create DOM elements, browser simply cannot keep up with it, easily at least. The canvas approach will be simpler and faster. Consequences for using canvas is that you cannot copy-paste content from it, you have to write mouse and keyboard handling yourself, it's harder to change the styling, and it is poor in accessibility (but this program isn't ideal for that to begin with). Obviously, most of the stats and information panels can be kept in html, since they don't change that much. Trace-Viewer uses canvas to draw the box content and overlays the other information with html elements, so there's also a precedent for using that approach. |
@egonelbre agree that physical things make more sense for such tool Regarding canvas, I thought that by canvas you mean a "fat client" (i.e. a desktop app). I don't have any opinion on HTML canvas. If that's the way to make it efficient, then let it be so. |
I misread what you said :D. I thought you were asking about HTML DOM vs. HTML canvas. Yes my initial idea was to provide a fat-client. For me difficult part is getting the window and input running across all platforms. Using a custom canvas and blitting it as a texture will be faster, because most of the pixel rows in the main display repeat - i.e. we can copy the same row multiple times. I've implemented widget rendering, so I pretty much know what awaits there, in this case there won't be much complication. We can use simple bitmap fonts as they will be clearer anyway when there is a lot of information. But after seeing the exp/shiny announcement I'll wait and see what they do, before starting with the fat client. (Obviously additionally have a working web client) |
We now handle large traces by splitting them up for the viewer (and have for some time). This works, but obviously it would be nice if we could view the whole trace at once, either through support for large traces in the Chrome trace viewer or through a custom trace viewer. I'm renaming the issue to reflect this. |
Here's an example.
x_test.go:
Do this:
$ go test -bench=. -trace=trace.out BenchmarkBlocking-8 500000 3401 ns/op $ go tool trace p.test trace.out
Then click on View trace.
Result: Browser tab crashes.
@egonelbre did an initial analysis on a related trace that came from real code (thanks, Egon!):
Given how easy it is to create giant (and thus unusable) traces, I think we should handle them gracefully, since the trace-viewer can't.
One option (perhaps not great): 'go tool trace' could allow you to specify a time window to display, and refuse to send windows that are too large to the trace viewer.
/cc @dvyukov @egonelbre
The text was updated successfully, but these errors were encountered: