0

Can an excessive use of smart pointers (especially shared_ptr) cause an increase in kernel calls?

I am trying to optimize and simplify a real-time (QNX) codebase. One focus besides memory and realtime efficiency is reducing system kernel calls. I've read through this and this, so I have a basic understanding that overusing shared_ptr's as call by value, might cause of some runtime performance issues. What I'm also curious about is whether this type of implementaions would also increase the kernel calls.

Please keep in mind that the processSend function is one of many functions that are called in a cycle and itself calls many other functions (like Default) in a similar way.

// getting called in every cycle (some milliseconds) void signal::processSend( std::shared_ptr<const structA> readPtrA, std::shared_ptr<const structB> readPtrB, std::shared_ptr<const structC> readPtrC) { last_send_data = this->Default(readPtrA, readPtrB, readPtrC); } void signal::Default( std::shared_ptr<const structA> readPtrA, std::shared_ptr<const structB> readPtrB, std::shared_ptr<const structC> readPtrC) { // some value readings } 
12
  • 7
    This can easily depend on the OS and the underlying CPU architecture. Point is, that the management of the reference counter must be performed in a way that is multithreading-safe, which may require OS support. Can you look at the implementation? Commented Nov 3, 2023 at 15:29
  • 4
    The above code causes two copies of the shared_ptr. Whether those do kernel calls is less important than that you're doing a bunch of redundant work instead of just moving stuff. At the very least, processSend should move its arguments into Default. Commented Nov 3, 2023 at 15:31
  • 1
    // some value readings: This doesn't require taking (shared) ownership of the objects, so the parameters of that function shouldn't be shared_ptrs to begin with and can be raw pointers (or even references) instead. And then going backwards the same holds for processSend as well. Commented Nov 3, 2023 at 15:34
  • 1
    BTW: Assuming an atomic reference counter, you need to get exclusive (from a CPU point of view) access, increment/decrement the value and then push the value back so that every other CPU will only see that value. That doesn't necessarily require OS support, but is an expensive operation nonetheless. In particular, it can't be performed in a register or L1 cache alone. Commented Nov 3, 2023 at 15:35
  • 1
    Basic rule of thumb: don't use std::shared_ptr when std::unique_ptr will do. std::unique_ptr is usually zero-overhead. Commented Nov 3, 2023 at 15:36

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.