Skip to content
Open
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
23 changes: 23 additions & 0 deletions cyber/benchmark/record/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
load("@bazel_tools//tools/cpp:cc.bzl", "cc_library", "cc_binary")

cc_library(
name = "record_reader_benchmark_lib",
srcs = ["record_reader_benchmark.cc"],
deps = [
"//path/to/record:record_reader", # Adjust this to your actual dependencies
"//path/to/record:record_writer",
"//path/to/base:base_lib", # Include necessary libraries
],
)

cc_binary(
name = "record_reader_benchmark",
srcs = ["record_reader_benchmark.cc"],
deps = [":record_reader_benchmark_lib"],
)

cc_binary(
name = "record_writer_benchmark",
srcs = ["record_writer_benchmark.cc"],
deps = ["//path/to/record:record_writer", "//path/to/base:base_lib"],
)
15 changes: 15 additions & 0 deletions cyber/benchmark/record/record_reader_benchmark.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "record_reader.h" // 示例模块

#include <benchmark/benchmark.h>

static void BM_ReadRecord(benchmark::State &state) {
RecordReader reader("path_to_record_file");
for (auto _ : state) {
reader.Read(); // 假设有一个 Read() 方法
}
}

// 将基准程序注册到 Google Benchmark
BENCHMARK(BM_ReadRecord)->Unit(benchmark::kMillisecond);

BENCHMARK_MAIN();
80 changes: 80 additions & 0 deletions cyber/benchmark/record/record_writer_benchmark.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#include <filesystem>
#include <string>
#include <vector>

#include <benchmark/benchmark.h>

#include "cyber/proto/record.pb.h"

#include "cyber/record/file/record_file_writer.h"

namespace apollo {
namespace cyber {
namespace record {

proto::SingleMessage CreateDummyMessage(size_t size_kb) {
proto::SingleMessage msg;
msg.set_channel_name("/apollo/sensor/camera/front_60");
msg.set_time(Time::Now().ToNanosecond());
msg.set_content(std::string(size_kb * 1024, 'x')); // Fill data
return msg;
}

static void BM_RecordWritePerformance(benchmark::State& state) {
const size_t message_size_kb = state.range(0);
const std::string test_file =
"test_perf_" + std::to_string(message_size_kb) + "kb.record";

RecordFileWriter writer;
if (!writer.Open(test_file)) {
state.SkipWithError("Could not open file for writing");
return;
}

// Write to Header and Channel
proto::Header header;
header.set_is_complete(false);
writer.WriteHeader(header);

proto::Channel channel;
channel.set_name("/apollo/sensor/camera/front_60");
channel.set_message_type("apollo.drivers.Image");
writer.WriteChannel(channel);

auto msg = CreateDummyMessage(message_size_kb);
size_t total_bytes = 0;

// Performance test core loop
for (auto _ : state) {
if (!writer.WriteMessage(msg)) {
state.SkipWithError("WriteMessage failed");
break;
}
total_bytes += msg.ByteSizeLong();
}

writer.Close();

// Statistics
state.SetBytesProcessed(static_cast<int64_t>(total_bytes));
state.SetLabel("MsgSize_" + std::to_string(message_size_kb) + "KB");

// Clean up test files.
std::filesystem::remove(test_file);
}

// Register test cases of different sizes
// 1: 1KB (IMU/Control)
// 64: 64KB (Lidar Clusters)
// 4096: 4MB (HD Camera Frame)
BENCHMARK(BM_RecordWritePerformance)
->Arg(1)
->Arg(64)
->Arg(4096)
->Unit(benchmark::kMillisecond);

} // namespace record
} // namespace cyber
} // namespace apollo

BENCHMARK_MAIN();
53 changes: 53 additions & 0 deletions cyber/record/file/aligned_buffer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#pragma once

namespace apollo {
namespace cyber {
namespace record {

#include <cstdlib>
#include <cstring>
#include <memory>
#include <stdexcept>

// 封装 posix_memalign,确保 4K 对齐
struct AlignedBuffer {
char* data = nullptr;
size_t size = 0;
size_t capacity = 0;

explicit AlignedBuffer(size_t cap) : capacity(cap) {
// Jetson 推荐 4KB 对齐,适配 Page Size
if (posix_memalign((void**)&data, 4096, capacity) != 0) {
throw std::runtime_error("Aligned alloc failed");
}
memset(data, 0, capacity);
}

~AlignedBuffer() { free(data); }

// 禁止拷贝,只许移动
AlignedBuffer(const AlignedBuffer&) = delete;
AlignedBuffer(AlignedBuffer&& other) noexcept {
data = other.data;
size = other.size;
capacity = other.capacity;
other.data = nullptr;
}

// 填充对齐 (O_DIRECT 要求写入大小必须是 Block Size 整数倍)
void Pad() {
size_t block_size = 4096;
size_t remainder = size % block_size;
if (remainder != 0) {
size_t padding = block_size - remainder;
if (size + padding <= capacity) {
memset(data + size, 0, padding); // 填充0
size += padding;
}
}
}
};

} // namespace record
} // namespace cyber
} // namespace apollo
Loading