-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
llvm-cov export spends most of its time in skipOtherFiles #62079
Comments
cc @bcardosolopes perhaps who has done some performance optimization work on |
cc @tunz and @vedantk who also landed EDIT: Oh, and perhaps @mysterymath since you seem to be the person who's generally contributing to coverage work these days. |
I have some work in progress that brings down a llvm-cov run on Firefox's libxul.so with a 2.5MB profile from 13 minutes down to 19 seconds. I'll open a PR when I'm 100% confident it doesn't break anything. |
When iterating over function records, filtered by file name, currently, the iteration goes over all the function records, repeatedly for each source file, essentially giving quadratic behavior. 413647d sped up some cases by keeping track of the indices of the function records corresponding to each file name. This change expands the use of that map to FunctionRecordIterator. On a test case with Firefox's libxul.so and a 2.5MB profile, this brings down the runtime of `llvm-cov export $lib --instr-profile $prof -t lcov` from 12 minutes with 90% spent in skipOtherFiles to 19 seconds with no samples in skipOtherFiles at all under a sampling profiler (with a sampling interval of 1ms). Fixes llvm#62079
When iterating over function records, filtered by file name, currently, the iteration goes over all the function records, repeatedly for each source file, essentially giving quadratic behavior. 413647d sped up some cases by keeping track of the indices of the function records corresponding to each file name. This change expands the use of that map to FunctionRecordIterator. On a test case with Firefox's libxul.so and a 2.5MB profile, this brings down the runtime of `llvm-cov export $lib --instr-profile $prof -t lcov` from 12 minutes with 90% spent in skipOtherFiles to 19 seconds with no samples in skipOtherFiles at all under a sampling profiler (with a sampling interval of 1ms). Fixes llvm#62079
When iterating over function records, filtered by file name, currently, the iteration goes over all the function records, repeatedly for each source file, essentially giving quadratic behavior. 413647d sped up some cases by keeping track of the indices of the function records corresponding to each file name. This change expands the use of that map to FunctionRecordIterator. On a test case with Firefox's libxul.so and a 2.5MB profile, this brings down the runtime of `llvm-cov export $lib --instr-profile $prof -t lcov` from 12 minutes with 90% spent in skipOtherFiles to 19 seconds with no samples in skipOtherFiles at all under a sampling profiler (with a sampling interval of 1ms). Fixes llvm#62079
When iterating over function records, filtered by file name, currently, the iteration goes over all the function records, repeatedly for each source file, essentially giving quadratic behavior. 413647d sped up some cases by keeping track of the indices of the function records corresponding to each file name. This change expands the use of that map to FunctionRecordIterator. On a test case with Firefox's libxul.so and a 2.5MB profile, this brings down the runtime of `llvm-cov export $lib --instr-profile $prof -t lcov` from 12 minutes with 90% spent in skipOtherFiles to 19 seconds with no samples in skipOtherFiles at all under a sampling profiler (with a sampling interval of 1ms). Fixes llvm#62079
As part of digging into a performance issue in a tool built on top of
llvm-cov
(specifically, it callsllvm-cov export
), I realized thatllvm-cov export
was taking upwards of 4s to run on a modestly-sized input. That is, it takes 4s to complete this invocation:where
some-binary
is a Rust binary of about 370M andsome.profdata
is 4M. And, during this time,llvm-cov
appears to be saturating a single core on my multi-core host.I built
llvm-cov
from the source inmain
and ran it throughperf
and Valgrind, and an interesting picture emerged (Firefox profiler visualization).llvm-cov
appears to be spending a majority of its time inllvm-project/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
Lines 209 to 215 in 88b7e8e
The calls to that function appear to stem from this call in
renderFile
:llvm-project/llvm/tools/llvm-cov/CoverageExporterLcov.cpp
Lines 179 to 181 in cae2a36
Which is ultimately called from
CoverageExporterLcov::renderRoot
viarenderFiles
.Valgrind appears to struggle to follow the full call-graph, but from what I can see, it appears that
skipOtherFiles
is called upwards of 650k times. It also appears to be the case thatrenderRoot
is itself called 300k times (possibly by itself — the call graph is unclear). In other words, it's not clear thatskipOtherFiles
itself is the problem (although it is doing a linear search as part of an iterator if I read it correctly?); the problem may be in the number of times it gets called. Perhaps some caching of its results are warranted?My lack of LLVM knowledge is preventing me from digging much further into this, but I'd be happy to run additional commands/instrument
llvm-cov
in whatever ways may be helpful to surface more information to track down the underlying issue.In case it matters, I'm running on an AArch64 host.
The text was updated successfully, but these errors were encountered: