sccn/lsl_archived

Replace src/endian with boost endian

Closed this issue · 1 comments

Endian conversion is done by conversion functions in src/endian copied from an older boost version.
Newer Boost versions use intrinsics for better performance, especially on weaker devices (e.g. arm).

Benchpress shows the following results (on a recent i5):

endian conversion src/endian		500000000           3 ns/op
endian conversion src/endian inplace	100000000          10 ns/op
endian conversion boost			1000000000           0 ns/op
endian conversion boost inplace		1000000000           0 ns/op

The benchmark code:

#define BENCHPRESS_CONFIG_MAIN
#include "../src/endian/conversion.hpp"
#include "benchpress.hpp"
#include 
#include 

/// Measure the endian conversion performance of this machine.
BENCHMARK("endian conversion src/endian\t\t", [](benchpress::context* ctx) {
	double data = 12335.5+ctx->num_iterations();
	for (size_t i = 0; i < ctx->num_iterations(); ++i) 
		lslboost::endian::reverse_value(data);
	benchpress::escape(&data);
})
BENCHMARK("endian conversion src/endian inplace\t", [](benchpress::context* ctx) {
	double data = 12335.5+ctx->num_iterations();
	for (size_t i = 0; i < ctx->num_iterations(); ++i) 
		lslboost::endian::reverse(data);
	benchpress::escape(&data);
})

BENCHMARK("endian conversion boost\t\t", [](benchpress::context* ctx) {
	double data = 12335.5+ctx->num_iterations();
	for (size_t i = 0; i < ctx->num_iterations(); ++i) 
		boost::endian::endian_reverse_inplace((uint64_t&) data);
	benchpress::escape(&data);
})

BENCHMARK("endian conversion boost inplace\t\t", [](benchpress::context* ctx) {
	double data = 12335.5+ctx->num_iterations();
	for (size_t i = 0; i < ctx->num_iterations(); ++i) 
		boost::endian::endian_reverse_inplace(*((uint64_t*) &data));
	benchpress::escape(&data);
})
//double measure_native_endian_performance() {

//}

BENCHMARK("correctness test", [](benchpress::context* ctx) {
	double data = 12335.5;
	std::cout << std::hex
	          << data << '\t';
	boost::endian::endian_reverse_inplace(*((uint64_t*) &data));
	std::cout << data << '\t';
	lslboost::endian::reverse(*((uint64_t*) &data));
	std::cout << data << '\t';
	*((uint64_t*) &data) = lslboost::endian::reverse_value(*((uint64_t*) &data));
	std::cout << data << '\t';
	*((uint64_t*) &data) = boost::endian::endian_reverse(*((uint64_t*) &data));
	std::cout << std::endl;
})