As general rules:
You should mark a function inline if you intent to define it in a header file (included by multiple translation units, aka .cpp files). It is not allowed to define a function which is not inline in multiple translation units. So this is necessary.
If the function is also static (at namespace scope), constexpr, is a function template or is defined inside a class definition, then inline is redundant and can/should be left out.
If the function is defined in a .cpp file and only used in this one translation unit it may be declared inline, but any performance implications of that are at best going to be minimal. A compiler will make its own decision on inlining anyway. inline is either completely ignored or a minor hint in the decision making process at best.
If the function is defined in a .cpp file and a declaration of it is included in multiple translation units via a header file, then it must not be declared inline. The inline specifier implies that you guarantee that a definition of the function will be available in any translation unit using it (and that all definitions will be identical).
The thing that is really performance-relevant here is not the inline specifier as such, but making the decision of whether you want to include the function definition in all translation units (meaning a header file) or only in one translation unit (meaning a .cpp file). Including in all translation units means that the compiler has it easier to perform inlining, not due to the inline keyword, but the fact that the definition is visible during the compilation process for the unit. However, nowadays we also have link time optimization which applies optimizations across all translation units when enabled and for which even that visibility of the definition doesn't really matter anymore.