Skip to content

Commit

Permalink
Merge pull request #3 from armeenm/datalog
Browse files Browse the repository at this point in the history
Improve performance for endian read/write functions
  • Loading branch information
PeterJohnson authored Mar 23, 2020
2 parents 0c7e3b4 + 182307b commit cb16c9a
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 65 deletions.
135 changes: 73 additions & 62 deletions wpiutil/examples/writelog/writelog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,89 +7,100 @@

#include <chrono>
#include <iostream>
#include <vector>
#include <array>
#include <string>
#include <numeric>

#include "wpi/DataLog.h"

int main() {
int main(int argc, char** argv) {
using std::chrono::duration_cast;
using std::chrono::high_resolution_clock;
using std::chrono::microseconds;

{
auto log = wpi::log::DoubleLog::Open("test.log", wpi::log::CD_CreateAlways);
if (!log) {
wpi::errs() << "could not open log\n";
return EXIT_FAILURE;
}
int kNumRuns = 10;

if (argc == 2)
kNumRuns = std::stoi(argv[1]);

auto testVec = std::vector<std::pair<std::string, void (*)()>>();

testVec.push_back({"50 double append (test.log)", []{
auto log =
wpi::log::DoubleLog::Open("test.log", wpi::log::CD_CreateAlways);

if (!log)
throw std::runtime_error("Could not open log");

for (int i = 0; i < 50; ++i) log->Append(20000 * i, 1.3 * i);
}
}});

{
auto start = high_resolution_clock::now();
{
wpi::log::DoubleLog::Config config;
config.periodicFlush = 1000;
auto log =
wpi::log::DoubleLog::Open("test2.log", wpi::log::CD_CreateAlways);
if (!log) {
wpi::errs() << "could not open log\n";
return EXIT_FAILURE;
}
for (int i = 0; i < 500000; ++i) log->Append(20000 * i, 1.3 * i);
}
auto stop = high_resolution_clock::now();
std::cout << " time: " << duration_cast<microseconds>(stop - start).count()
<< "\n";
}
#if 0
{
std::vector<uint8_t> data;
data.resize(5000);
auto start = high_resolution_clock::now();
{
auto log = wpi::log::DataLog::Open("test2.log", "image", "image", 0,
wpi::log::CD_OpenAlways);
if (!log) {
wpi::errs() << "could not open log\n";
return EXIT_FAILURE;
}
for (int i = 0; i < 1000; ++i) log->Append(20000 * i, data);
}
auto stop = high_resolution_clock::now();
std::cout << " time: " << duration_cast<microseconds>(stop - start).count()
<< "\n";
}
#endif
{
testVec.push_back({"500k double append (test2.log)", []{
wpi::log::DoubleLog::Config config;
config.periodicFlush = 1000;
auto log =
wpi::log::StringLog::Open("test-string.log", wpi::log::CD_CreateAlways);
if (!log) {
wpi::errs() << "could not open log\n";
return EXIT_FAILURE;
}
for (int i = 0; i < 50; ++i) log->Append(20000 * i, "hello");
wpi::log::DoubleLog::Open("test2.log", wpi::log::CD_CreateAlways);

if (!log)
throw std::runtime_error("Could not open log");

for (uint64_t i = 0; i < 500000; ++i) log->Append(20000 * i, 1.3 * i);
}});

/*
testVec.push_back("Int array append (test2.log)", []{
auto data = std::vector<uint8_t>(5000);
auto log = wpi::log::DataLog::Open("test2.log", "image", "image", 0,
wpi::log::CD_OpenAlways);
if (!log)
throw std::runtime_error("Could not open log");
for (int i = 0; i < 1000; ++i) log->Append(20000 * i, data);
}
*/

{
testVec.push_back({"50 string append (test-string.log)", []{
auto log = wpi::log::StringLog::Open("test-string.log",
wpi::log::CD_CreateAlways);
if (!log)
throw std::runtime_error("Could not open log");

for (int i = 0; i < 50; ++i) log->Append(20000 * i, "hello");
}});

testVec.push_back({"Double array append (test-double-array.log)", []{
auto log = wpi::log::DoubleArrayLog::Open("test-double-array.log",
wpi::log::CD_CreateAlways);
if (!log) {
wpi::errs() << "could not open log\n";
return EXIT_FAILURE;
}
if (!log)
throw std::runtime_error("Could not open log");

log->Append(20000, {1, 2, 3});
log->Append(30000, {4, 5});
}
}});

{
testVec.push_back({"String array append (test-string-array.log)", []{
auto log = wpi::log::StringArrayLog::Open("test-string-array.log",
wpi::log::CD_CreateAlways);
if (!log) {
wpi::errs() << "could not open log\n";
return EXIT_FAILURE;
}
if (!log)
throw std::runtime_error("Could not open log");

log->Append(20000, {"Hello", "World"});
log->Append(30000, {"This", "Is", "Fun"});
}});

for (const auto& [name, fn] : testVec) {
auto resVec = std::vector<microseconds::rep>();
std::cout << name << ": ";

for (int i = 0; i < kNumRuns; ++i) {
auto start = high_resolution_clock::now();
fn();
auto stop = high_resolution_clock::now();
resVec.push_back(duration_cast<microseconds>(stop - start).count());
}

std::cout << std::accumulate(resVec.begin(), resVec.end(), 0)/kNumRuns << "us\n";
}

return EXIT_SUCCESS;
Expand Down
5 changes: 5 additions & 0 deletions wpiutil/src/main/native/cpp/DataLog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -549,8 +549,13 @@ wpi::Expected<DataLog> DataLog::Open(const wpi::Twine& filename,
DataLog log(new DataLogImpl, true);
if (wpi::Error e = log.m_impl->DoOpen(filename, dataType, dataLayout,
recordSize, disp, config))
#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ < 8
return std::move(e);
return std::move(log);
#else
return e;
return log;
#endif
}

bool DoubleLog::Append(uint64_t timestamp, double value) {
Expand Down
10 changes: 10 additions & 0 deletions wpiutil/src/main/native/include/wpi/DataLog.h
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,11 @@ class DataLogStaticMixin {
if (wpi::Error e =
impl->Check(Derived::kDataType, Derived::kDataLayout,
Derived::kRecordSize, true, checkLayout, true))
#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ < 8
return std::move(e);
#else
return e;
#endif
return Derived(impl, false);
}

Expand Down Expand Up @@ -718,8 +722,14 @@ class DataLogStaticMixin {
if (wpi::Error e = log.GetImpl()->DoOpen(
filename, Derived::kDataType, Derived::kDataLayout,
Derived::kRecordSize, disp, config))

#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ < 8
return std::move(e);
return std::move(log);
#else
return e;
return log;
#endif
}
};

Expand Down
17 changes: 14 additions & 3 deletions wpiutil/src/main/native/include/wpi/Endian.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ inline value_type byte_swap(value_type value, endianness endian) {
/// Swap the bytes of value to match the given endianness.
template<typename value_type, endianness endian>
inline value_type byte_swap(value_type value) {
return byte_swap(value, endian);
if constexpr ((endian != native) && (endian != system_endianness()))
sys::swapByteOrder(value);
return value;
}

/// Read a value of a particular endianness from memory.
Expand All @@ -87,7 +89,13 @@ template<typename value_type,
endianness endian,
std::size_t alignment>
inline value_type read(const void *memory) {
return read<value_type, alignment>(memory, endian);
value_type ret;

memcpy(&ret,
LLVM_ASSUME_ALIGNED(
memory, (detail::PickAlignment<value_type, alignment>::value)),
sizeof(value_type));
return byte_swap<value_type, endian>(ret);
}

/// Read a value of a particular endianness from a buffer, and increment the
Expand Down Expand Up @@ -118,7 +126,10 @@ template<typename value_type,
endianness endian,
std::size_t alignment>
inline void write(void *memory, value_type value) {
write<value_type, alignment>(memory, value, endian);
value = byte_swap<value_type, endian>(value);
memcpy(LLVM_ASSUME_ALIGNED(
memory, (detail::PickAlignment<value_type, alignment>::value)),
&value, sizeof(value_type));
}

template <typename value_type>
Expand Down

0 comments on commit cb16c9a

Please sign in to comment.