2017-02-23 84 views
0

У меня есть шаблон доступа к памяти в моей программе, как ...Если доступ по адресу-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 адрес находится далеко.

+0

Нет, я так не думаю. – immibis

+0

@immibis Спасибо, это ценный комментарий. – javaLover

+0

что вы ожидаете * он может узнать *? Всегда загружать c с помощью b не будет более эффективным в последнем процессоре AFAICT. –

ответ

1

В вашем случае bs[iSecret] это один адрес, который пытается получить доступ к какому-либо другому адресу c через doSomething()

Это так, чтобы принять логический уровень пользователя, который пользователя может только оптимизировать путем соответствующего размещения данных заостренных ваших Ь и с преимущество пространственной локальности.

Как простой пример, ожидаете ли вы, что компилятор будет оптимизировать этот код?

int a[100][100]; 
for(int i = 0; i < 100; ++i) 
for(int j = 0; j < 100; ++j) 
    cout << a[j][i] << endl; 

Однако бы это был случай условной конструкции, как

address X: if(condition) 
      { 
address Y:  //dosomething_A 
      } 
      else 
      { 
address Z: //dosomething_B 
      } 

Здесь if условия на address X и так далее ..

В таких условных конструкциях компилятор может генерировать код, который может минимизировать штрафы цикла сваливания (из-за ветки) на конвейерных процессорах.

Кроме того, конвейерные процессоры могут узнать о ваших филиалах, используя Branch_predictor во время выполнения.

+0

Я не очень хорошо разбираюсь в английском, не могли бы вы ответить в заявлении без вопросов, пожалуйста? Спасибо! – javaLover

+0

Все говорят, что логика уровня пользователя не может быть оптимизирована/предсказана компилятором/процессором. Но компилятор может оптимизировать конструкции языка программирования, поскольку он знает об этих конструкциях. Точно так же CPU может оптимизировать/предсказать поток команд, потому что он имеет дело с этими вещами. – sameerkn

+0

Я пытаюсь это понять. Ваш ответ означает: «Ответ - нет. Я должен сделать так, чтобы b и c имели аналогичный адрес. Для этого я должен управлять вручную, например, вашим первым примером». ? – javaLover

 Смежные вопросы

  • Нет связанных вопросов^_^