Сколько разных указателей / уровней косвенного обращения здесь доступно?

У меня есть четыре класса, представляющих наследование и иерархию композиции:

class A{
//Structure here not important
}

class B : public A{
int a;
shared_ptr<C> c;
}

class C{
shared_ptr<D> d;
}

class D{
std::list<int> e;
}

Тогда у меня есть vector<shared_ptr<A>>Я повторяю и суммирую *begin() значения из двух D std::list<int> объекты:

for(int i = 0; i< vec.size(); i++){
shared_ptr<B> b = vec[i];
shared_ptr<C> c = b->c;
sum += *(c->d->e.begin());
}

Я пытаюсь выяснить, сколько отдельных обращений к строкам кэша может быть сделано за каждую итерацию цикла (если мы предположим наихудший сценарий, когда каждый уровень косвенности / указателя хранится в отдельной строке кэша).

На данный момент я рассчитал 7,25 различных строк кэша за одну итерацию:

  1. Доступ к shared_ptr<A> в vec[i] (это 0,25, потому что sizeof(shared_ptr<A>)/64)
  2. Доступ к A объект vec[i] указывает на
  3. Доступ к shared_ptr<C> с указывает на
  4. Доступ к C объект c указывает на
  5. Доступ к shared_ptr<D> объект для д
  6. Доступ к объекту D d
  7. Доступ к d«s std::list<int> e указатель
  8. Доступ к d«s *begin() данные

Я что-то пропустил? Я не уверен, если объекты, созданные в стеке внутри цикла (b а также c) может храниться в разных строках кэша указателей, к которым они обращаются (vec[i] а также b->c).

1

Решение

Добавлен ответ, чтобы дополнить разговор в комментариях

Вот ваш цикл с некоторыми комментариями:

for(int i = 0; i< vec.size(); i++){
shared_ptr<B> b = vec[i];  // create 1 copy of vec[i] - increments share cout
shared_ptr<C> c = b->c;    // create 1 copy of b->c - increments share cout
sum1 += *(c->d1->e.begin());  // merely dereference pointer
sum2 += *(c->d2->e.begin());  // merely dereference pointer
}

Вы можете сохранить несколько копий, и, следовательно, некоторые строки кэша пропустят, если вы напишите это так:

for(int i = 0; i< vec.size(); i++){
// take reference only - no copy.
//const means I promise not to modify the pointer object.
const shared_ptr<B>& b = vec[i];

// take reference only - no copy.
//const means I promise not to modify the pointer object.
const shared_ptr<C>& c = b->c;  // dereference b (which is really vec[i])

sum1 += *(c->d1->e.begin());  // merely dereference pointer
sum2 += *(c->d2->e.begin());  // merely dereference pointer
}
1

Другие решения