c++ - Does accessing via a shared_ptr pollute the cache line more than raw pointer? -


i understand compiler can perform optimization accessing, int* via std::shared_ptr done using same assembly if raw int* pointer used.

my question is: cache line containing optimized smart pointer polluted other data members smart pointer, reference counter? although assembly generated identical real pointer, cache performance worse because not of cache line being used efficiently?

edit: performance effect more-noticeable if iterating through structure std::vector<std::shared_ptr<int>> , using ints.

i have reasons believe worrying wrong thing.

consider following 2 snippets:

#include <cstdio> #include <memory> #include <vector>  int main() {   std::vector<std::shared_ptr<int>> v = { std::make_shared<int>(1),                                            std::make_shared<int>(2),                                           std::make_shared<int>(3) };   (auto& e : v)     std::printf("%d\n", *e); } 

and same functionality unique_ptr:

#include <cstdio> #include <memory> #include <vector>  template<typename t, typename... args> std::unique_ptr<t> make_unique(args&&... args) {     return std::unique_ptr<t>(new t(std::forward<args>(args)...)); }  int main() {   std::vector<std::unique_ptr<int>> v;   v.reserve(3);   v.emplace_back(make_unique<int>(1));   v.emplace_back(make_unique<int>(2));   v.emplace_back(make_unique<int>(3));   (auto& e : v)     std::printf("%d\n", *e); } 

just answer question:

this performance effect more-noticeable if iterating through structure std::vector<std::shared_ptr<int>> , using ints.

here corresponding loops:

    shared_ptr version   |    unique_ptr version .l66:                    | .l70:     movq    (%rbx), %rax |    movq    (%rbx), %rax     movl    $.lc0, %esi  |    movl    $.lc0, %esi     movl    $1, %edi     |    movl    $1, %edi     movl    (%rax), %edx |    movl    (%rax), %edx     xorl    %eax, %eax   |    xorl    %eax, %eax .lehb2:                  |.lehb6:     call    __printf_chk |    call    __printf_chk .lehe2:                  |.lehe6:     addq    $16, %rbx    |    addq    $8, %rbx     cmpq    %rbx, %rbp   |    cmpq    %rbx, %rbp     jne    .l66          |    jne    .l70 

the relevant difference doing larger steps shared_ptr when reading memory. in both cases memory access pattern if linear fixed stride length. i failed come scenario there measurable difference between two.

in opinion, answers question.


some unsolicited advice, show you worrying wrong thing. analyze generated assembly code 2 code snippets above (g++ -std=c++11 -wall -wextra -pedantic -fwhole-program -o3 -s , run assembly through c++filt). find out shared_ptr heavy weight object compared unique_ptr. see expensive construct , destroy shared_ptrs, , maintain atomic reference counts; pay heavy weight multi-threading machinery well.

i know questionable metric assembly code shared_ptr 740 lines, , code unique_ptr 402 lines. if analyze construction , destruction of objects, notice more code executed shared_ptr and many of instructions more expensive (expensive multi-threading stuff). shared_ptr consumes more memory bookkeeping (on these silly code snippets: 144 vs. 36 bytes, is, 4 times more shared_ptr).

potential cache misses last thing worry @ point.


Comments

Popular posts from this blog

Why can rails not find a route created by a helper? -

javascript - jquery or ashx not working -

opencv - DataType<cv::detail::deriv_type>::depth what is it used for -