AVX/main.cpp
2025-05-09 16:21:15 -07:00

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;
}