255 lines
6.8 KiB
C++
255 lines
6.8 KiB
C++
#include <ehs/Types.h>
|
|
#include <ehs/io/Console.h>
|
|
#include <ehs/io/File.h>
|
|
#include <ehs/system/CPU.h>
|
|
#include <ehs/system/AVX2.h>
|
|
#include <ehs/system/AVX512.h>
|
|
|
|
bool Compare_AVX512(const void* const a, const void* const b, const ehs::UInt_64 size)
|
|
{
|
|
ehs::Byte* aBytes = (ehs::Byte*)a;
|
|
ehs::Byte* bBytes = (ehs::Byte*)b;
|
|
ehs::UInt_64 remainder = size;
|
|
ehs::UInt_64 i = 0;
|
|
|
|
while (i < size)
|
|
{
|
|
if (remainder >= 64)
|
|
{
|
|
if (!ehs::AVX512::CompareUnaligned((ehs::UInt_64*)&aBytes[i], (ehs::UInt_64*)&bBytes[i]))
|
|
return false;
|
|
|
|
i += 64;
|
|
}
|
|
else if (remainder >= 32)
|
|
{
|
|
if (!ehs::AVX2::CompareUnaligned((ehs::UInt_64*)&aBytes[i], (ehs::UInt_64*)&bBytes[i]))
|
|
return false;
|
|
|
|
i += 32;
|
|
}
|
|
else if (remainder >= sizeof(ehs::UInt_64))
|
|
{
|
|
if (*(ehs::UInt_64*)&aBytes[i] != *(ehs::UInt_64*)&bBytes[i])
|
|
return false;
|
|
|
|
i += sizeof(ehs::UInt_64);
|
|
}
|
|
else if (remainder >= sizeof(ehs::UInt_32))
|
|
{
|
|
if (*(ehs::UInt_32*)&aBytes[i] != *(ehs::UInt_32*)&bBytes[i])
|
|
return false;
|
|
|
|
i += sizeof(ehs::UInt_32);
|
|
}
|
|
else if (remainder >= sizeof(ehs::UInt_16))
|
|
{
|
|
if (*(ehs::UInt_16*)&aBytes[i] != *(ehs::UInt_16*)&bBytes[i])
|
|
return false;
|
|
|
|
i += sizeof(ehs::UInt_16);
|
|
}
|
|
else
|
|
{
|
|
if (aBytes[i] != bBytes[i])
|
|
return false;
|
|
|
|
i += sizeof(ehs::Byte);
|
|
}
|
|
|
|
remainder = size - i;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool Compare_AVX2(const void* const a, const void* const b, const ehs::UInt_64 size)
|
|
{
|
|
ehs::Byte* aBytes = (ehs::Byte*)a;
|
|
ehs::Byte* bBytes = (ehs::Byte*)b;
|
|
ehs::UInt_64 remainder = size;
|
|
ehs::UInt_64 i = 0;
|
|
|
|
while (i < size)
|
|
{
|
|
if (remainder >= 32)
|
|
{
|
|
if (!ehs::AVX2::CompareUnaligned((ehs::UInt_64*)&aBytes[i], (ehs::UInt_64*)&bBytes[i]))
|
|
return false;
|
|
|
|
i += 32;
|
|
}
|
|
else if (remainder >= sizeof(ehs::UInt_64))
|
|
{
|
|
if (*(ehs::UInt_64*)&aBytes[i] != *(ehs::UInt_64*)&bBytes[i])
|
|
return false;
|
|
|
|
i += sizeof(ehs::UInt_64);
|
|
}
|
|
else if (remainder >= sizeof(ehs::UInt_32))
|
|
{
|
|
if (*(ehs::UInt_32*)&aBytes[i] != *(ehs::UInt_32*)&bBytes[i])
|
|
return false;
|
|
|
|
i += sizeof(ehs::UInt_32);
|
|
}
|
|
else if (remainder >= sizeof(ehs::UInt_16))
|
|
{
|
|
if (*(ehs::UInt_16*)&aBytes[i] != *(ehs::UInt_16*)&bBytes[i])
|
|
return false;
|
|
|
|
i += sizeof(ehs::UInt_16);
|
|
}
|
|
else
|
|
{
|
|
if (aBytes[i] != bBytes[i])
|
|
return false;
|
|
|
|
i += sizeof(ehs::Byte);
|
|
}
|
|
|
|
remainder = size - i;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool Compare(const void* const a, const void* const b, const ehs::UInt_64 size)
|
|
{
|
|
ehs::Byte* aBytes = (ehs::Byte*)a;
|
|
ehs::Byte* bBytes = (ehs::Byte*)b;
|
|
ehs::UInt_64 remainder = size;
|
|
ehs::UInt_64 i = 0;
|
|
|
|
while (i < size)
|
|
{
|
|
if (remainder >= sizeof(ehs::UInt_64))
|
|
{
|
|
if (*(ehs::UInt_64*)&aBytes[i] != *(ehs::UInt_64*)&bBytes[i])
|
|
return false;
|
|
|
|
i += sizeof(ehs::UInt_64);
|
|
}
|
|
else if (remainder >= sizeof(ehs::UInt_32))
|
|
{
|
|
if (*(ehs::UInt_32*)&aBytes[i] != *(ehs::UInt_32*)&bBytes[i])
|
|
return false;
|
|
|
|
i += sizeof(ehs::UInt_32);
|
|
}
|
|
else if (remainder >= sizeof(ehs::UInt_16))
|
|
{
|
|
if (*(ehs::UInt_16*)&aBytes[i] != *(ehs::UInt_16*)&bBytes[i])
|
|
return false;
|
|
|
|
i += sizeof(ehs::UInt_16);
|
|
}
|
|
else
|
|
{
|
|
if (aBytes[i] != bBytes[i])
|
|
return false;
|
|
|
|
i += sizeof(ehs::Byte);
|
|
}
|
|
|
|
remainder = size - i;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
int main()
|
|
{
|
|
ehs::Initialize("AVX", "Release", {1, 0, 0});
|
|
ehs::Log::EnableImmediateMode(true);
|
|
|
|
ehs::Console::Write_8("File Path:");
|
|
ehs::Str_8 filePath = ehs::Console::Read_8();
|
|
|
|
ehs::File file(filePath, ehs::Mode::READ, ehs::Disposition::OPEN);
|
|
|
|
ehs::Console::Write_8("\nFile Size: " + ehs::Str_8::FromNum(file.Size() / 1024 / 1024) + "MB\n");
|
|
|
|
ehs::Console::Write_8("Reading file...");
|
|
|
|
const ehs::Array<ehs::Byte> data1 = file.ReadArray(file.Size());
|
|
|
|
ehs::Console::Write_8("Copying file data...");
|
|
const ehs::Array<ehs::Byte> data2 = data1;
|
|
file.Release();
|
|
|
|
ehs::Console::Write_8("Calculating TSC Frequency...\n");
|
|
ehs::UInt_64 freq = ehs::CPU::GetTSC_Freq();
|
|
ehs::UInt_64 start;
|
|
ehs::UInt_64 end;
|
|
|
|
ehs::Console::Write_8("Control");
|
|
|
|
start = ehs::CPU::GetTSC();
|
|
|
|
const bool resultControl = Compare(data1, data2, data1.Size());
|
|
|
|
end = ehs::CPU::GetTSC();
|
|
|
|
ehs::Console::Write_8("Result: ", false);
|
|
if (resultControl)
|
|
ehs::Console::Write_8("Equal");
|
|
else
|
|
ehs::Console::Write_8("Not Equal");
|
|
|
|
ehs::Console::Write_8("Start: " + ehs::Str_8::FromNum(start));
|
|
ehs::Console::Write_8("End: " + ehs::Str_8::FromNum(end));
|
|
ehs::Console::Write_8("Elapsed Time: " + ehs::Str_8::FromNum((double)(end - start) / (double)freq) + "s\n");
|
|
|
|
ehs::Console::Write_8("AVX2");
|
|
if (ehs::CPU::hasAVX2)
|
|
{
|
|
start = ehs::CPU::GetTSC();
|
|
|
|
const bool resultAVX2 = Compare_AVX2(data1, data2, data1.Size());
|
|
|
|
end = ehs::CPU::GetTSC();
|
|
|
|
ehs::Console::Write_8("Result: ", false);
|
|
if (resultAVX2)
|
|
ehs::Console::Write_8("Equal");
|
|
else
|
|
ehs::Console::Write_8("Not Equal");
|
|
|
|
ehs::Console::Write_8("Start: " + ehs::Str_8::FromNum(start));
|
|
ehs::Console::Write_8("End: " + ehs::Str_8::FromNum(end));
|
|
ehs::Console::Write_8("Elapsed Time: " + ehs::Str_8::FromNum((double)(end - start) / (double)freq) + "s\n");
|
|
}
|
|
else
|
|
{
|
|
ehs::Console::Write_8("Not Supported\n");
|
|
}
|
|
|
|
ehs::Console::Write_8("AVX-512");
|
|
if (ehs::CPU::hasAVX512F)
|
|
{
|
|
start = ehs::CPU::GetTSC();
|
|
|
|
const bool resultAVX512 = Compare_AVX512(data1, data2, data1.Size());
|
|
|
|
end = ehs::CPU::GetTSC();
|
|
|
|
ehs::Console::Write_8("Result: ", false);
|
|
if (resultAVX512)
|
|
ehs::Console::Write_8("Equal");
|
|
else
|
|
ehs::Console::Write_8("Not Equal");
|
|
|
|
ehs::Console::Write_8("Start: " + ehs::Str_8::FromNum(start));
|
|
ehs::Console::Write_8("End: " + ehs::Str_8::FromNum(end));
|
|
ehs::Console::Write_8("Elapsed Time: " + ehs::Str_8::FromNum((double)(end - start) / (double)freq) + "s\n");
|
|
}
|
|
else
|
|
{
|
|
ehs::Console::Write_8("Not Supported\n");
|
|
}
|
|
|
|
ehs::Uninitialize();
|
|
|
|
return 0;
|
|
} |