Skip to content

Instantly share code, notes, and snippets.

@GravisZro
Created April 24, 2024 22:01
Show Gist options
  • Select an option

  • Save GravisZro/d397b1c7c09712d58581c48ae29615e4 to your computer and use it in GitHub Desktop.

Select an option

Save GravisZro/d397b1c7c09712d58581c48ae29615e4 to your computer and use it in GitHub Desktop.
#include <sys/time.h>
#include <sys/resource.h>
#include <x86intrin.h>
#include <cassert>
#include <cstdint>
#include <cstdlib>
#include <byteswap.h>
#include <iostream>
#define get_time(output) \
output = __rdtsc();
namespace D3
{
// std::byteswap from C++23
template <typename T> constexpr T byteswap(T n) {
T m;
for (size_t i = 0; i < sizeof(T); i++)
reinterpret_cast<uint8_t *>(&m)[i] = reinterpret_cast<uint8_t *>(&n)[sizeof(T) - 1 - i];
return m;
}
}
int main(void)
{
if(setpriority(PRIO_PROCESS, 0, -20) != 0)
{
std::cout << "Must be run with superuser privileges" << std::endl;
return 0;
}
constexpr const uint64_t swaps_per_test = 0xFFFFFF;
uint16_t a = 0;
uint32_t b = 0;
uint64_t c = 0;
uint64_t count = 0;
uint64_t start, stop;
uint64_t records[6];
std::cout << "Performing " << swaps_per_test << " swaps per test." << std::endl;
count = swaps_per_test;
get_time(start);
do {
a = D3::byteswap(start^a);
} while(--count);
get_time(stop);
std::cerr << "value 16: " << a << std::endl;
records[0] = stop - start;
std::cout << "D3::byteswap<uint16_t>() took " << records[0] << " cycles, an average of " << (double(records[0]) / swaps_per_test) << " cycles per call" << std::endl;
count = swaps_per_test;
get_time(start);
do {
b = D3::byteswap(start^b);
} while(--count);
get_time(stop);
std::cerr << "value 32: " << b << std::endl;
records[1] = stop - start;
std::cout << "D3::byteswap<uint32_t>() took " << records[1] << " cycles, an average of " << (double(records[1]) / swaps_per_test) << " cycles per call" << std::endl;
count = swaps_per_test;
get_time(start);
do {
c = D3::byteswap(start^c);
} while(--count);
get_time(stop);
std::cerr << "value 64: " << c << std::endl;
records[2] = stop - start;
std::cout << "D3::byteswap<uint64_t>() took " << records[2] << " cycles, an average of " << (double(records[2]) / swaps_per_test) << " cycles per call" << std::endl;
count = swaps_per_test;
get_time(start);
do {
a = bswap_16(start^a);
} while(--count);
get_time(stop);
std::cerr << "value 16: " << a << std::endl;
records[3] = stop - start;
std::cout << "bswap_16() took " << records[3] << " cycles, an average of " << (double(records[3]) / swaps_per_test) << " cycles per call" << std::endl;
count = swaps_per_test;
get_time(start);
do {
b = bswap_32(start^b);
} while(--count);
get_time(stop);
std::cerr << "value 32: " << b << std::endl;
records[4] = stop - start;
std::cout << "bswap_32() took " << records[4] << " cycles, an average of " << (double(records[4]) / swaps_per_test) << " cycles per call" << std::endl;
count = swaps_per_test;
get_time(start);
do {
c = bswap_64(start^c);
} while(--count);
get_time(stop);
std::cerr << "value 32: " << c << std::endl;
records[5] = stop - start;
std::cout << "bswap_64() took " << records[5] << " cycles, an average of " << (double(records[5]) / swaps_per_test) << " cycles per call" << std::endl;
std::cout << "bswap_16 was " << (float(records[0])/float(records[3])) << " times faster." << std::endl;
std::cout << "bswap_32 was " << (float(records[1])/float(records[4])) << " times faster." << std::endl;
std::cout << "bswap_64 was " << (float(records[2])/float(records[5])) << " times faster." << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment