Различное время выполнения программы на C ++ в cmd.exe и Powershell - PullRequest
2 голосов
/ 29 мая 2020

Я тестировал эту довольно простую программу:

#include <Windows.h>
#include <stdio.h>

void dotp(float *array1, float *array2, float *dest, size_t N) {
  for (size_t i = 0; i < N; ++i) {
      dest[i] += array1[i] * array2[i];
  }
}

float *newArray(int N) {
  float *x = new float[N];
  for (size_t i = 0; i < N; ++i) {
    x[i] = i;
  }
  return x;
}

int main(int argc, const char *argv[])
{
  SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
  LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
  LARGE_INTEGER Frequency;

  size_t LOOPS = 10 * 1000 * 1000;
  int N =  1024;

  float* x = newArray(N);
  float* y = newArray(N);
  float* z = newArray(N);

  QueryPerformanceFrequency(&Frequency); 
  QueryPerformanceCounter(&StartingTime);
  for (size_t i = 0; i < LOOPS; ++i) {
    dotp(x, y, z, N);
  }
  QueryPerformanceCounter(&EndingTime);
  ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;
  ElapsedMicroseconds.QuadPart *= 1000000;
  ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;

  printf("%lld\r\n", Frequency.QuadPart);
  QueryPerformanceFrequency(&Frequency); 
  printf("%lld\r\n", ElapsedMicroseconds.QuadPart);
  printf("%lld\r\n", Frequency.QuadPart);

  return 0;
}

и компилировал ее с помощью cl.exe /arch:AVX2 /O2 main.cpp.

При запуске в cmd.exe требуется около 1 секунды для запуска (Я сделал много запусков, без разницы):

.\main.exe
10000000
1023448
10000000

Однако при запуске в Powershell это существенно (и постоянно на протяжении многих запусков, независимо от того, что еще происходит в моем OS) быстрее:

 .\main.exe
10000000
620746
10000000

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

cmd /v:on /c "echo !time! & .\main.exe & echo !time!
11:59:11.38
10000000
1004120
10000000
11:59:12.39
 Measure-Command {.\main.exe}


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 630
Ticks             : 6308918
TotalDays         : 7.30198842592593E-06
TotalHours        : 0.000175247722222222
TotalMinutes      : 0.0105148633333333
TotalSeconds      : 0.6308918
TotalMilliseconds : 630.8918

Я напечатал частоту счетчика производительности до и после профилированного кода в если произошло изменение, а также установить класс приоритета процесса на тот случай, если cmd.exe и Powershell обработали его по-разному. Никаких различий.

Вдобавок к этому , как только включаете iostream и используете его для печати чего-то еще , cmd.exe и Powershell дают эквивалентные результаты (увеличение скорости для cmd.exe, снижение скорости для Powershell).

#include <Windows.h>
#include <stdio.h>
#include <iostream>

void dotp(float *array1, float *array2, float *dest, size_t N) {
  for (size_t i = 0; i < N; ++i) {
      dest[i] += array1[i] * array2[i];
  }
}

float *newArray(int N) {
  float *x = new float[N];
  for (size_t i = 0; i < N; ++i) {
    x[i] = i;
  }
  return x;
}

int main(int argc, const char *argv[])
{
  SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
  LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
  LARGE_INTEGER Frequency;

  size_t LOOPS = 10 * 1000 * 1000;
  int N =  1024;

  float* x = newArray(N);
  float* y = newArray(N);
  float* z = newArray(N);

  QueryPerformanceFrequency(&Frequency); 
  QueryPerformanceCounter(&StartingTime);
  for (size_t i = 0; i < LOOPS; ++i) {
    dotp(x, y, z, N);
  }
  QueryPerformanceCounter(&EndingTime);
  ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;
  ElapsedMicroseconds.QuadPart *= 1000000;
  ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;

  printf("%lld\r\n", Frequency.QuadPart);
  QueryPerformanceFrequency(&Frequency); 
  printf("%lld\r\n", ElapsedMicroseconds.QuadPart);
  printf("%lld\r\n", Frequency.QuadPart);
  std::cout << "blah" << std::endl;

  return 0;
}

cmd.exe:

.\main.exe
10000000
776086
10000000
blah

Powershell:

.\main.exe
10000000
763109
10000000
blah

Я не знаю, как объяснить эти расхождения.

1 Ответ

2 голосов
/ 29 мая 2020

Сроки подачи заявки - ДЕЙСТВИТЕЛЬНО СЛОЖНАЯ сделка. Причина этого в том, что вы НЕ используете операционную систему реального времени.

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

Отметьте это, чтобы лучше понять, почему ваш код не работает правильно: https://en.wikipedia.org/wiki/Scheduling_ (вычисления)

Надеюсь, я помог

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...