У меня есть четыре класса, представляющих наследование и иерархию композиции:
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 различных строк кэша за одну итерацию:
shared_ptr<A>
в vec[i]
(это 0,25, потому что sizeof(shared_ptr<A>)/64
)A
объект vec[i]
указывает наshared_ptr<C>
с указывает наC
объект c
указывает наshared_ptr<D>
объект для дD d
d
«s std::list<int> e
указательd
«s *begin()
данныеЯ что-то пропустил? Я не уверен, если объекты, созданные в стеке внутри цикла (b
а также c
) может храниться в разных строках кэша указателей, к которым они обращаются (vec[i]
а также b->c
).
Добавлен ответ, чтобы дополнить разговор в комментариях
Вот ваш цикл с некоторыми комментариями:
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
}