Неожиданное меньшее время доступа в сценарии с несколькими процессами по сравнению с сценарием с одним процессом

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

Теперь, когда я выполняю program2 (с пустым циклом while, чтобы удержать его от завершения) сначала на другой вкладке, затем запускаю program1 и измеряю время доступа для чтения всех элементов этого массива. К моему удивлению, теперь я получаю 8000 тиков по сравнению с предыдущим сценарием, где выполняется только Program1.

Похоже, что пока выполняется ТОЛЬКО program1, для чтения массива требуется больше времени по сравнению с тем, когда есть 2 программы, program1 выполняет ту же задачу, что и предыдущая, а program2 поддерживает ЦП в цикле while. Ожидается большее время доступа при наличии программы1, тогда как реальный результат противоположен.

Почему это происходит?

Вот общая библиотека

#include <stdio.h> 
static const int DATA[1024]={1 ,2 ,3,.....1024];
inline void foo(void)
{
    int j, k=0,count=0;

    for(j=0;j<1024;j++)
      {
        k=DATA[j];
      }

    k+=0;    
}

Program1

   int main(void)
    {    
    foo();

    start=timer();
    foo();
    end=timer();
    printf("Time1=%llu\n",end-start);    

    start=timer();
    foo();
    end=timer();
    printf("Time2=%llu\n",end-start);    


    start=timer();
    foo();
    end=timer();
    printf("Time3=%llu\n",end-start); 
    sleep(1);

    start=timer();
    foo();
    end=timer();
    printf("after sleep(1)\n");
    printf("Time4=%llu\n",end-start);    

    start=timer();
    foo();
    end=timer();
    printf("Time5=%llu\n",end-start);    

    sleep(2); 
    start=timer();
    foo();
    end=timer();
    printf("after sleep(2)\n");
    printf("Time6=%llu\n",end-start);    

    return 0;
    }

program2

   int main(void)
    {
    while(1)
        {}        
    return 0;
    }

CASE1 (работает ТОЛЬКО программа1)

выход

Time1=17918
Time2=17672  
Time3=17816  

after sleep(1)
**Time4= 20716 ** // Is it due to wake up from sleep mode ?
Time5=17722

after sleep(2)
**Time6=20910** // Is it due to wake up from sleep mode ?

CASE1 (сначала запускается Program2, затем запускается Program1)

выход

Time1 =7483  
Time2=7205
Time3=7399

after sleep(1)
**Time4= 8734 ** // Is it due to wake up from sleep mode ?
Time5=7326

after sleep(2)
**Time6=9070** // Is it due to wake up from sleep mode ?

Насколько я понимаю, в то время как процессор используется только программой program1, время, необходимое для чтения массива, должно быть меньше по сравнению с тем, как процессор используется как программой Program1, так и программой2.

Где я делаю ошибки? У меня машина i7, только одно ядро, гиперпоточность отключена, ASLR отключен.

РЕДАКТИРОВАТЬ 1:

Согласно предложению Mysticial, мой ЦП переходит в режим энергосбережения, когда там находится ТОЛЬКО программа1, поэтому ЦП переходит в режим энергосбережения, а затем, чтобы выйти из режима энергосбережения, требуется больше времени доступа. Поэтому он предложил несколько раз получить доступ к массиву данных.

Вот моя модифицированная общая библиотека. Программа 1 и Программа 2 не изменены.

#include <stdio.h> 
static const int DATA[1024]={1 ,2 ,3,.....1024];
inline void foo(void)
{
    int j, k=0,count=0;
  while(count++<10000)
  {  
    for(j=0;j<1024;j++)
      {
        k=DATA[j];
      }
   }  
    k+=0;    
}

Теперь вывод как ниже

CASE1 (работает ТОЛЬКО программа1)

выход

Time1=75186246
Time2=77570299 
Time3=80548529 

after sleep(1)
**Time4= 92608363 ** // Is it due to wake up from sleep mode ?
Time5=75616487

after sleep(2)
**Time6=97021338** // Is it due to wake up from sleep mode ?

CASE1 (сначала запускается Program2, затем запускается Program1)

выход

Time1 =139337099 
Time2=155801957
Time3=146586856

after sleep(1)
**Time4= 130558062 ** // Why lower access time after sleep mode ?
Time5=145250551 // Time5 is expected lower than Time4 as other run . Why lower here ?

after sleep(2)
**Time6=130940183** // Again Why lower access time after sleep mode ?

Вот мои новые вопросы относительно модифицированной разделяемой библиотеки

  1. Если нет программы 2, то после времени доступа в спящем режиме (t4/t6) оно выше по сравнению с предыдущим временем доступа (t3/t5, перед переходом в спящий режим). Могу ли я сказать, что это происходит из-за пробуждения процессора из сна, как объясняет Mysticial?

  2. Теперь, когда программа 2 работает на другой вкладке, время доступа после перехода в спящий режим (t4/t6) меньше по сравнению с предыдущим временем доступа (t3/t5, перед переходом в спящий режим). Причина, по которой мои q(1) и q(2) противоречивы. В чем причина получения меньшего времени доступа после пробуждения от сна (t4

  3. Зачем t2<t1 and t3<t2 не всегда имеет значение true, поскольку разделяемая библиотека уже загружена в память и кэш. Это связано с переключением страниц?

Я использую GCC под Linux. Любая помощь, чтобы понять это, будет высоко оценен. Заранее спасибо.

1 ответ

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

В исходном тесте вы запускаете только одну итерацию каждого. Таким образом, тест не выполняется достаточно долго, чтобы "усреднить" всю случайность.

Когда вы запускаете program1 самостоятельно, ему нужно вывести процессор из состояния энергосбережения. Это занимает время и, вероятно, приводит к увеличению времени выполнения.

Когда вы запускаете обе программы вместе (сначала начиная с program2), program2 заблаговременно выводит процессор из состояния энергосбережения. Таким образом, этот штраф за разминку не реализуется при запуске программы1.


Как только вы зацикливаетесь на тесте, который занимает больше времени, этот штраф за разогрев становится незначительным, и вы, наконец, видите ожидаемую производительность кода в установившемся режиме. (программа1 сама по себе быстрее)

Другие вопросы по тегам