I have quite stupid class task: measure which types works faster in C++. Firstly I thought "it`s obvious, that the fastest type is the type that corresponds to processor word-size, so it will be int64_t on my AMD Ryzen 7 2700x) and, of course, double and float will be much slower than ints. I wrote simple program, but can`t explain its output to myself... Probably, I`m missing something. (compiled in x64 release msvc142).
#include <vector>
#include <chrono>
#include <array>
template <typename T>
T** newMatr1(size_t n)
{
T** res = new T * [n];
for (size_t i = 0; i < n; i++)
{
res[i] = new T[n];
}
return res;
}
template <typename T>
void delMatr1(T** matr, size_t n)
{
for (size_t i = 0; i < n; i++)
{
delete[] matr[i];
}
delete matr;
}
template <typename T>
void initMatr(T** matr, size_t n)
{
for (size_t i = 0; i < n; i++)
{
for (size_t j = 0; j < n; j++)
{
matr[i][j] = rand();
}
}
}
template <typename T>
void multiplyMatr(T** matr1, T** matr2, size_t n)
{
T** res = newMatr1<T>(n);
for (size_t i = 0; i < n; ++i)
{
for (size_t j = 0; j < n; ++j)
{
for (size_t k = 0; k < n; ++k)
{
res[i][j] += matr1[i][k] * matr2[k][j];
}
}
}
delMatr1(res, n);
}
template <typename T>
std::vector<std::vector<T>> initVec(size_t n)
{
std::vector<std::vector<T>> matr(n, std::vector<T>(n));
for (size_t i = 0; i < n; i++)
{
for (size_t j = 0; j < n; j++)
{
matr[i][j] = rand();
}
}
return matr;
}
template <typename T>
void multiplyVect(const std::vector<std::vector<T>>& matr1, const std::vector<std::vector<T>>& matr2, size_t n)
{
std::vector<std::vector<T>> res(n, std::vector<T>(n));
for (size_t i = 0; i < n; ++i)
{
for (size_t j = 0; j < n; ++j)
{
for (size_t k = 0; k < n; ++k)
{
res[i][j] += matr1[i][k] * matr2[k][j];
}
}
}
}
template <typename Func, typename T>
std::chrono::high_resolution_clock::duration getMinTime(Func function, const T& matr1, const T& matr2, int n, int count)
{
auto min = std::chrono::high_resolution_clock::duration::max();
for (size_t i = 0; i < count; ++i)
{
auto start = std::chrono::high_resolution_clock::now();
function(matr1, matr2, n);
auto end = std::chrono::high_resolution_clock::now();
auto diff = end - start;
if(diff < min)
min = diff;
}
return min;
}
template <typename T>
void getTime()
{
std::vector<size_t> sizes{ 512 };// , 1024, 2048
for (int i = 0; i < sizes.size(); ++i)
{
std::cout << sizes[i] << ":\n";
std::cout << "std::vector: ";
std::vector<std::vector<T>> vec1 = initVec<T>(sizes[i]);
std::vector<std::vector<T>> vec2 = initVec<T>(sizes[i]);
std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(getMinTime(multiplyVect<T>, vec1, vec2, sizes[i], 10)).count() << "ms";
std::cout << " arr(raw ptr): ";
T** matr1 = newMatr1<T>(sizes[i]);
T** matr2 = newMatr1<T>(sizes[i]);
initMatr(matr1, sizes[i]);
initMatr(matr2, sizes[i]);
std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(getMinTime(multiplyMatr<T>, matr1, matr2, sizes[i], 10)).count() << "ms\n";
delMatr1(matr1, sizes[i]);
delMatr1(matr2, sizes[i]);
}
}
int main()
{
std::vector<size_t> sizes{ 512, 1024 }; //, 2048
std::cout << "int8_t\n";
getTime<int8_t>();
std::cout << "int16_t\n";
getTime<int16_t>();
std::cout << "int32\n";
getTime<int>();
std::cout << "int64_t\n";
getTime<int64_t>();
std::cout << "float\n";
getTime<float>();
std::cout << "double\n";
getTime<double>();
system("pause");
}
the output I got:
int8_t
512:
std::vector: 233ms arr(raw ptr): 228ms
int16_t
512:
std::vector: 233ms arr(raw ptr): 230ms
int32
512:
std::vector: 237ms arr(raw ptr): 235ms
int64_t
512:
std::vector: 250ms arr(raw ptr): 236ms
float
512:
std::vector: 104ms arr(raw ptr): 104ms
double
512:
std::vector: 106ms arr(raw ptr): 106ms
what is wrong? Why floats and doubles are much faster that ints? And why double not slower than float?
Flags:
/permissive- /GS /GL /W3 /Gy /Zc:wchar_t /Zi /Gm- /O2 /sdl /Fd"x64\Release\vc142.pdb" /Zc:inline /fp:precise /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd /Oi /MD /FC /Fa"x64\Release" /EHsc /nologo /Fo"x64\Release" /Ot /Fp"x64\Release\tmp.pch" /diagnostics:column