Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AlignedBuffer: avoid unnecessary data copying when already aligned #32698

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions cereal/messaging/messaging.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <algorithm>
#include <cstddef>
#include <map>
#include <string>
Expand Down Expand Up @@ -86,17 +87,25 @@ class PubMaster {
class AlignedBuffer {
public:
kj::ArrayPtr<const capnp::word> align(const char *data, const size_t size) {
words_size = size / sizeof(capnp::word) + 1;
if (aligned_buf.size() < words_size) {
aligned_buf = kj::heapArray<capnp::word>(words_size < 512 ? 512 : words_size);
const size_t word_count = size / sizeof(capnp::word);

// Check if data is already aligned
if (reinterpret_cast<uintptr_t>(data) % alignof(capnp::word) == 0) {
return kj::arrayPtr(reinterpret_cast<const capnp::word *>(data), word_count);
}

// Data is not aligned, perform alignment
if (aligned_buf.size() < word_count) {
aligned_buf = kj::heapArray<capnp::word>(std::max(word_count, size_t(512)));
}
memcpy(aligned_buf.begin(), data, size);
return aligned_buf.slice(0, words_size);
memcpy(aligned_buf.begin(), data, word_count * sizeof(capnp::word));
return aligned_buf.slice(0, word_count);
}

inline kj::ArrayPtr<const capnp::word> align(Message *m) {
return align(m->getData(), m->getSize());
}

private:
kj::Array<capnp::word> aligned_buf;
size_t words_size;
};
6 changes: 5 additions & 1 deletion cereal/messaging/socketmaster.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <assert.h>
#include <stdlib.h>
#include <string>
#include <memory>
#include <mutex>

#include "cereal/services.h"
Expand Down Expand Up @@ -40,6 +41,7 @@ struct SubMaster::SubMessage {
bool is_polled = false;
capnp::FlatArrayMessageReader *msg_reader = nullptr;
AlignedBuffer aligned_buf;
std::unique_ptr<Message> message;
cereal::Event::Reader event;
};

Expand Down Expand Up @@ -92,8 +94,10 @@ void SubMaster::update(int timeout) {
m->msg_reader->~FlatArrayMessageReader();
capnp::ReaderOptions options;
options.traversalLimitInWords = kj::maxValue; // Don't limit

// Reset the message buffer to the new one. Keep it for the message reader's lifetime.
m->message.reset(msg);
m->msg_reader = new (m->allocated_msg_reader) capnp::FlatArrayMessageReader(m->aligned_buf.align(msg), options);
delete msg;
messages.push_back({m->name, m->msg_reader->getRoot<cereal::Event>()});
}

Expand Down
Loading