I was benchmarking this fairly simple program:
#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;
}
and compiling it with cl.exe /arch:AVX2 /O2 main.cpp.
When running it in in cmd.exe, it takes about 1 seconds to run (I did many runs, no difference):
.\main.exe
10000000
1023448
10000000
However when running it in Powershell, it's substantially (and consistently over many runs, no matter what else is going on in my OS) faster:
.\main.exe
10000000
620746
10000000
Using some simple shell commands corroborate what the performance counters say:
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
I printed the performance counter frequency before and after the profiled code in case there was a change and also set the priority class of the process just in case cmd.exe and Powershell treated it differently. No differences.
On top of that, as soon as include iostream and use it to print something else, the cmd.exe and Powershell give equivalent results (speed increase for cmd.exe, speed decrease for 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
I'm not sure how to explain these discrepancies.