Skip to content

Instantly share code, notes, and snippets.

@maneesh29s
Created April 4, 2023 07:23
Show Gist options
  • Select an option

  • Save maneesh29s/2e3c588dc6f0c8587392c09c0f82e016 to your computer and use it in GitHub Desktop.

Select an option

Save maneesh29s/2e3c588dc6f0c8587392c09c0f82e016 to your computer and use it in GitHub Desktop.
This programs tests the performance difference caused due to endian conversion
// simple swapping without data types
#include <assert.h>
#include <chrono>
#include <cstring>
#include <iostream>
#include <ratio>
#include <vector>
#define SIZE_CAN_FLOAT 4
namespace chrono = std::chrono;
class Timer {
private:
chrono::time_point<chrono::high_resolution_clock> start;
chrono::time_point<chrono::high_resolution_clock> end;
public:
void start_timer() { this->start = chrono::high_resolution_clock::now(); }
void stop_timer() { this->end = chrono::high_resolution_clock::now(); }
std::string time_elapsed() {
auto time_taken =
chrono::duration_cast<chrono::microseconds>(this->end - this->start)
.count();
return std::to_string(time_taken) + " us";
}
};
std::vector<float> generateRandomData(size_t size, float range, float offset) {
std::vector<float> arr(size);
time_t seed = time(0);
srand(seed);
for (size_t i = 0; i < size; i++) {
arr[i] = offset + range * (rand() / (float)RAND_MAX);
}
return arr;
}
inline void reverse4(void *to, const void *from) {
unsigned int x, xsw;
memcpy(&x, from, 4);
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
xsw = __builtin_bswap32(x);
#else
xsw = ((x & 0xffu) << 24u) | ((x & 0xff00u) << 8u) | ((x & 0xff0000u) >> 8u) |
(x >> 24u);
#endif
memcpy(to, &xsw, 4);
}
inline size_t toLocal(float &to, const void *from) {
// #if defined(AIPS_LITTLE_ENDIAN)
reverse4(((char *)&to) + sizeof(float) - 4, from);
// #else
// move4 (&to, from);
// #endif
return SIZE_CAN_FLOAT;
}
size_t TOLOCAL(int CONVERT, void *to, const void *from, size_t nr) {
int SIZE = sizeof(float);
/* Use memcpy if no conversion is needed. */
if (CONVERT == 0) {
assert(sizeof(float) == SIZE);
memcpy(to, from, nr * SIZE);
} else {
const char *data = (const char *)from;
float *dest = (float *)to;
float *last = dest + nr;
while (dest < last) {
toLocal(*dest++, data);
data += SIZE;
}
}
return nr * SIZE;
}
int main() {
// #if (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__))
// #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
// printf("__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ \n\n");
// #endif
// #endif
// #if defined(__APPLE__)
// printf("__APPLE__ is defined by default");
// #endif
size_t SIZE = 1000000000;
size_t bytesOperated;
Timer t;
std::vector<float> inVec;
inVec = generateRandomData(SIZE, 100.0, -50.0);
std::vector<float> outVecNormal(SIZE);
t.start_timer();
bytesOperated = TOLOCAL(0, outVecNormal.data(), inVec.data(), SIZE);
t.stop_timer();
std::cout << "bytesOperated : " << bytesOperated << std::endl;
std::cout << "Time elapsed normal : " << t.time_elapsed() << std::endl;
inVec = generateRandomData(SIZE, 100.0, -50.0);
std::vector<float> outVecReversed(SIZE);
t.start_timer();
bytesOperated = TOLOCAL(1, outVecReversed.data(), inVec.data(), SIZE);
t.stop_timer();
std::cout << "bytesOperated : " << bytesOperated << std::endl;
std::cout << "Time elapsed reversed : " << t.time_elapsed() << std::endl;
}
@maneesh29s
Copy link
Copy Markdown
Author

To compile:

g++ -std=c++14 -o <exectuable_path> spike_endian_conversion.cpp

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment