1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
# Tuning Cppcheck Analysis
There are several ways you can potentially improve the runtime of a Cppcheck analysis.
Note: Most of these suggestions highly depend on your code base so they need to be evaluated before being applied. They might also depend the code of Cppcheck itself and your environment. So you might want to evaluate these on a regular basis.
## Collecting Information
To see the time each file took to analyze just specify the `--showtime=file-total` CLI option.
## Tuning At Build-Level
It is most likely that a pre-built binary is being used - either an official one or one provided by the packaging manager of my operating system.
But if you build your own binary it is possible to apply several steps to potentially improve the performance.
Note: Recently more distribution have opted to use more advanced optimization for their packages so several of the following suggestions might have already been applied.
Please refer to the documentation of your distribution for more insight on this.
### Use Matchcompiler
(TODO: document how to use it when using the in-tree Visual Studio project)
(TODO: check with a CMake generated Visual Studio project)
### Use Boost
Boost.Container (https://www.boost.org/doc/libs/release/libs/container) is being used for some containers which have a smaller overhead.
As the used library is header-only implementation you only need to install the package on the system you build the binary on but not on the system you run the analysis on.
The official Windows binary is always using this.
This will be used by default if Boost is detected in CMake. If you want to enforce the usage, you can use the CMake option `-DUSE_BOOST=On` which will cause the build to fail if no Boost was detected.
Using Visual Studio you need to provide a full Boost release (i.e. including binaries) for it to be detected by CMake. If you are not able to do this you can specify the CMake option `-DBOOST_INCLUDEDIR=<in>` (pointing to the directory which *contains* the `boost` include directory) to work around this (this is a Cppcheck specific hack) - see https://trac.cppcheck.net/ticket/13822 for more details.
If you are using `make` instead you need to specify `-DHAVE_BOOST` in the flags.
If you are using the Visual Studio project you need to specify the properties `HaveBoost` (always needs to be set to `HAVE_BOOST`) and `BoostInclude` (set to the Boost folder). On the command-line you would need to add `-p:HaveBoost=HAVE_BOOST -p:BoostInclude=<boostdir>`.
### Use A Different Compiler
Analyzing our own code base has shown that using a different compiler might lead to slightly better performance.
In our case Clang is mostly faster than GCC. See https://trac.cppcheck.net/ticket/10778 for some details.
### Use More Advanced Optimizations
By default we enforce the `-O2` optimization level. Even when using the `Release` build type in CMake which defaults to `-O3`. It might be possible that building with `-O3` might yield a perfomance increase.
There are also no additional code generation flags provided so the resulting binary can run on any system. You might be able to tune this and apply more optimization which is tailored to the system you will be running the binary on.
Needs to be evaluated. (TODO: file tickets)
### Use LTO
Needs to be evaluated. See https://trac.cppcheck.net/ticket/11671.
### Use profile-guided optimizations (PGO/BOLT/AutoFDO/Propeller)
Needs to be evaluated. See https://trac.cppcheck.net/ticket/11672.
## Tuning At Analysis-Level
### Use A More Performant Platform
It seems people assume that you need to run the analysis on the same system you build your code on/for. That is not necessary as the analysis is system-agnostic.
As system headers are not required for analyzing your code you only need to specify the configuration which matches the system you run your code on.
In case you are using a project as input which can only be generated on the build/target system you can just transfer that to a different system and still run the analysis.
### Specify A Build Dir
Using the `--cppcheck-build-dir` allows you to perform incremental runs which omit files which have not been changed.
Important: As this is currently seriously lacking in testing coverage it might have shortcomings and need to be used with care. (TODO: file ticket)
### Exclude Static/Generated Files
If your code base contains files which rarely change (e.g. local copies of external dependencies) or you have generated files (e.g. `moc_*.cpp` for Qt projects) you might consider excluding these from the analysis.
This can be done by using the `-i` option on the CLI, `<ignore>` in GUI projects or by including them to begin with into the files passed to the analysis.
Depending on your setup you might also consider to scan these files in a less frequent run (e.g. only when the files have changed or Cppcheck was updated).
This could also be handled using `--cppcheck-build-dir` (see above).
### Exclude System Headers
System headers are not necessary to perform the analysis. So you might consider not providing those to the analysis and specify a library configuration via `--library` instead.
`pkg-config` for instance will always provide non-system includes.
(TODO: file ticket about ignoring all braced includes)
### Limit The Configuration
By default configuration to analyze will be determined automatically for each file based on the code. The maximum amount is limited and can be controlled by CLI options.
Depending on your setup you might want to limit it to specific configuration by using `-D` (CLI) or `--project-configuration=` (Visual Studio project).
When you are using a compilation database generated by CMake it is already using a fixed configuration.
### Use Multiple Jobs
By default only a single process/thread is being used. You might to scale this up using the `-j` CLI option. Please note that specifying a value that will max out your systems resources might have a detrimental effect.
### Use A Different Threading Model
When using multiple job for the analysis (see above) on Linux it will default to using processes. This is done so the analysis is not aborted prematurely aborted in case of a crash.
Unfortunately it has overhead because of a suboptimal implementation and the fact that data needs to be transferred from the child processes to the main process.
So if you do not require the additional safety you might want to switch to the usage of thread instead using `--executor=thread`.
Note: For Windows binaries we currently do not provide the possibility of using processes so this does not apply.
### Disable Analyzing Of Unused Templated Functions
Currently all templated functions (either locally or in headers) will be analyzed regardless if they are instantiated or not. If you have template-heavy includes that might lead to unnecessary work and findings, and might slow down the analysis. This behavior can be disabled with `--no-check-unused-templates`.
Note: This might lead to "false negatives" in such functions if they are never instantiated. You should make sure that you have proper coverage of the affected functions in your code before enabling this.
### Limit Analysis Of Projects
If you specify a project all files will be analyzed by default. But in some cases you might only be interested in the results in a subset of those (e.g. in IDE integrations).
Using the `--file-filter=<pattern>` CLI option you can select files using a globbing syntax. Using `--file-filter=-` you can provide the filters directly on the CLI.
## Advanced Tuning
### Re-order The Files
Files which take longer to analyze should be processed at first so they might not extended the run time. As the order how the files provided on the CLI or via the project are being honored it is as simple as that.
### Adjust Thresholds
There are lots of internal thresholds which limit the work which is put into parts of the analysis. The defaults were chosen as a compromise of time being spent vs. issues being detected but not might not be a good fit in all cases.
These thresholds are currently neither exposed nor documented so they cannot be changed without the modifying the source which is *highly discouraged*.
They are being utilized internally by `-check-level` though (see below).
(TODO: file ticket about providing all bailouts)
(TODO: file ticket about expose these)
(TODO: file ticket about specifying these per file)
Note: As these will lead to less data being collected for the analysis it might lead to false negatives *and* false positives.
### Adjust Check Level
There are several check levels which are basically a collection of different threshold values (see above). This can be adjusted by the CLI option `--check-level`.
Note: The current default is the lowest available check level.
Note: As these will lead to less data being collected for the analysis it might lead to false negatives *and* false positives.
## Reporting Issues
If you encounter a file which has an unreasonable slow analysis please consider reporting this as an issue.
Also consider reporting major upticks in the runtime of the analysis after updating to a newer version. Some of these might be expected as the analysis is constantly improved but out-of-the-box we still need aim for reasonable times.
In all cases please try to provide a small reproducer if possible.
Note: There might even be cases the analysis will never finish because it is stuck in a cycle. This is quite uncommon but there are still several unresolved known cases so it is possible to encounter this.
### Known Issues
https://trac.cppcheck.net/ticket/10663
https://trac.cppcheck.net/ticket/10765
https://trac.cppcheck.net/ticket/10778
https://trac.cppcheck.net/ticket/11262
https://trac.cppcheck.net/ticket/12528
https://trac.cppcheck.net/ticket/13698
|