Depends on D88415
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
clang-tools-extra/clangd/ClangdLSPServer.cpp | ||
---|---|---|
171 | this change is a bit puzzling - makes it look like there are some cases where we specifically want/don't want to record. why? | |
172 | on the flip side processing cancellations as fast as possible seems like it might be important. Maybe just move the recording of memory usage to the happy case? (Notification that we have a handler for, after the handler). | |
179 | after each notification? | |
181 | maybe move this into a tiny function? It's self-contained, a bit distracting from the fairly important core logic here, and we may well want to do it conditionally or in more/different places in future. | |
184 | (Sorry, I suspect we discussed this and I forgot) |
this is at least going to take some important locks, hopefully only briefly.
We should watch the timing here carefully and consider guarding it - apart from the minimum time interval we discussed, we could have a check whether metric tracing is actually enabled in a meaningful way.
Bad news, I was testing this with remote-index, hence background-index was turned off. Unfortunately traversing all of the slabs in FileSymbols takes quite a while in this case (~15ms for LLVM).
I don't think it is feasible to do this on every notification now, as this implies an extra 15ms latency for interactive requests like code completion/signature help due to the delay between didChange notification and codeCompletion request.
We should watch the timing here carefully and consider guarding it - apart from the minimum time interval we discussed, we could have a check whether metric tracing is actually enabled in a meaningful way.
I've also added early exit for non-tracing case. But I think we should still change this to be periodic or once every N calls. WDYT?
clang-tools-extra/clangd/ClangdLSPServer.cpp | ||
---|---|---|
171 | it was to ensure we have a ClangdServer instance we can query for memory usage. will revert as moving profiling into happy case makes it obselete. | |
184 |
Not really.
ClangdLSPServer didnt feel like the appropriate place for that logic. Moreover other embedders of ClangdServer could benefit from traversal logic if it is defined in a lower level than ClangdLSPServer. |
Yeah, 15ms is a lot.
Staring at the code, I think this is our unfortunate index allocation strategy: for each source file in the project, we have one slab allocator for symbols, one for refs, one for relations...
The factor of 3 is sad but the factor of 10000 is what's killing us :-)
So we should fix that someday (DBMS?) but for now, let's back off to measuring once every several minutes.
The main problem I see is that we're almost guaranteed to be "unlucky" with the sample that way.
e.g. delay = 5 min. On startup there's some notification (initialized? didOpen?) that happens before any of the serious allocation and resets the counter.
So we won't have a realistic memory usage until we hit the 5 minute mark and profile again. If many sessions are <5min then our averages are going to be way off.
I can't think of a notification that is ubiquitous but only fires after serious work has happened. (Well, publishDiagnostics, but that goes in the wrong direction and so runs on the wrong thread).
What about something like a 5 minute throttle, but have ClangdLSPServer's constructor set the timestamp to now+1 minute? (Without profiling)
clang-tools-extra/clangd/ClangdLSPServer.cpp | ||
---|---|---|
153 | I was about to complain that this doesn't work, but it actually does... This wasn't the intended design of trace/span :-( Do you mind adding an explicit trace::enabled() method to Trace.h instead, to be more explicit? I'd like to fix the Trace api. | |
184 | (Sorry, I guess D88413 was really the place for this discussion)
To me, putting this in ClangdLSPServer feels like "this isn't part of the central mission here, it could be split out for coherence/reuse".
If exporting memorytree->metric with the path as the label is something we want to reuse, that could be a function in MemoryTree.h (taking the metric as parameter) or we can include the generic traversal function you proposed earlier. Even though they're both in Support, layering MemoryTree above Tracer seems more appropriate than the other way around. |
What about something like a 5 minute throttle, but have ClangdLSPServer's constructor set the timestamp to now+1 minute? (Without profiling)
SGTM. Note that this means we can't easily test this in LSP layer anymore. (We've got couple of components depending on time, maybe it is time we have a "mock" clock?)
clang-tools-extra/clangd/ClangdLSPServer.cpp | ||
---|---|---|
184 |
Added a record member to MemoryTree in D88413. |
clang-tools-extra/clangd/ClangdLSPServer.cpp | ||
---|---|---|
1242 | ClangdLSPServer does own things other than ClangdServer (e.g. the CDB), though we don't yet profile them. | |
1242 | Detailed is always false, drop the parameter? This can't be reused by code wanting to e.g. service a code action anyway. | |
1432 | As written this isn't clearly true or false (what exactly is "startup"?) | |
clang-tools-extra/clangd/ClangdLSPServer.h | ||
173 | or NextProfileTime? (to avoid the negation) |
clang-tools-extra/clangd/ClangdLSPServer.h | ||
---|---|---|
72 | drop the no-op part? |
drop the no-op part?