У меня есть шаблон доступа к памяти в моей программе, как ...Если доступ по адресу-B, как правило, следует за доступом к адресу-C, может ли кэш распознать его?
b1->c1 (b and c are address.)
//.... do something else ....
b2->c2
//.... do something else ....
b3->c3
....
Является ли компилятор/кэш/CPU достаточно умен, чтобы признать, что:
, когда я загружаю b
, он должен (подготовить к) нагрузки, соответствующие c
?
Подробнее: Можете ли вы каким-то образом предсказать мой шаблон доступа и каким-то образом его оптимизировать?
Насколько это выгодно, примерно?
Я создал a test case. Результат показывает, что он не может учиться во время выполнения.
(В реальных случаях B
имеет много полей, но, как правило ->
только c
.)
class C{
public: int data=0;
};
class B{
public: C* c; int accu=0;
public: B(){
c=new C();
}
public: void doSomething(){
accu+=c->data; //do something about c
}
};
int main() {
using namespace std;
const int NUM=1000000;
B* bs[NUM];
for(int n=0;n<NUM;n++){
bs[n]=new B();
}
for(int loop=0;loop<20;loop++){
double accumulator=0;
for(int n=0;n<NUM;n++){
int iSecret = rand() % NUM;
clock_t begin = clock();
bs[iSecret]->doSomething();
clock_t end = clock();
accumulator+=double(end - begin);
}
double elapsed_secs = accumulator;
std::cout<<elapsed_secs<<std::endl;
}
}
Print (время в цикле)
Если он может узнать, позже петли должны используйте меньше времени, чем предыдущие.
298749
306951
332946
...
337232
Я не думаю, что он может использовать Spatial locality, потому что c
«s адрес находится далеко.
Нет, я так не думаю. – immibis
@immibis Спасибо, это ценный комментарий. – javaLover
что вы ожидаете * он может узнать *? Всегда загружать c с помощью b не будет более эффективным в последнем процессоре AFAICT. –