674 lines
27 KiB
C++
674 lines
27 KiB
C++
// ================================================================================================
|
|
// Audio Backend - 性能基准测试
|
|
// ================================================================================================
|
|
// 描述: 测试系统各组件的性能指标
|
|
// ================================================================================================
|
|
|
|
#include "fixtures/integration_test_fixtures.h"
|
|
#include "engine/audio_buffer.h"
|
|
#include "communication/communication.h"
|
|
#include "plugin_host/manager/plugin_host_manager.h"
|
|
#include "frontend/manager/frontend_manager.h"
|
|
#include <thread>
|
|
#include <chrono>
|
|
#include <atomic>
|
|
#include <mutex>
|
|
#include <condition_variable>
|
|
#include <algorithm>
|
|
#include <numeric>
|
|
#include <random>
|
|
|
|
using namespace audio_backend;
|
|
using namespace audio_backend::test;
|
|
using namespace std::chrono_literals;
|
|
|
|
// 性能测试配置
|
|
struct PerformanceTestConfig {
|
|
// 音频参数
|
|
uint32_t sample_rate = DEFAULT_SAMPLE_RATE;
|
|
uint16_t channels = DEFAULT_CHANNELS;
|
|
engine::AudioFormat format = engine::AudioFormat::FLOAT32;
|
|
uint32_t buffer_size = DEFAULT_BUFFER_SIZE;
|
|
|
|
// 测试参数
|
|
uint32_t warmup_iterations = 10; // 预热迭代次数
|
|
uint32_t benchmark_iterations = 100; // 基准测试迭代次数
|
|
uint32_t stress_test_duration_ms = 10000; // 压力测试持续时间
|
|
uint32_t concurrency_level = 4; // 并发级别
|
|
|
|
// 性能阈值
|
|
double max_latency_ms = 10.0; // 最大可接受延迟
|
|
double max_cpu_usage_percent = 80.0; // 最大CPU使用率
|
|
double max_memory_usage_mb = 500.0; // 最大内存使用
|
|
uint32_t min_throughput_buffers_per_sec = 100; // 最低吞吐量
|
|
};
|
|
|
|
// 性能测试结果
|
|
struct PerformanceTestResult {
|
|
// 延迟统计
|
|
std::vector<double> latency_ms;
|
|
double min_latency_ms = 0.0;
|
|
double max_latency_ms = 0.0;
|
|
double avg_latency_ms = 0.0;
|
|
double median_latency_ms = 0.0;
|
|
double p95_latency_ms = 0.0; // 95th百分位数
|
|
double p99_latency_ms = 0.0; // 99th百分位数
|
|
|
|
// 吞吐量统计
|
|
uint32_t total_buffers_processed = 0;
|
|
uint32_t buffers_per_second = 0;
|
|
|
|
// 资源使用
|
|
double peak_cpu_usage_percent = 0.0;
|
|
double avg_cpu_usage_percent = 0.0;
|
|
double peak_memory_usage_mb = 0.0;
|
|
|
|
// 测试信息
|
|
std::string test_name;
|
|
std::chrono::milliseconds test_duration{0};
|
|
|
|
// 计算统计数据
|
|
void calculate_statistics() {
|
|
if (latency_ms.empty()) return;
|
|
|
|
// 排序用于计算百分位数
|
|
std::sort(latency_ms.begin(), latency_ms.end());
|
|
|
|
// 基本统计
|
|
min_latency_ms = latency_ms.front();
|
|
max_latency_ms = latency_ms.back();
|
|
avg_latency_ms = std::accumulate(latency_ms.begin(), latency_ms.end(), 0.0) / latency_ms.size();
|
|
|
|
// 中位数
|
|
median_latency_ms = latency_ms[latency_ms.size() / 2];
|
|
|
|
// 百分位数
|
|
size_t p95_index = static_cast<size_t>(latency_ms.size() * 0.95);
|
|
size_t p99_index = static_cast<size_t>(latency_ms.size() * 0.99);
|
|
p95_latency_ms = latency_ms[p95_index];
|
|
p99_latency_ms = latency_ms[p99_index];
|
|
}
|
|
|
|
// 结果是否通过性能要求
|
|
bool passes_thresholds(const PerformanceTestConfig& config) const {
|
|
return p95_latency_ms <= config.max_latency_ms &&
|
|
peak_cpu_usage_percent <= config.max_cpu_usage_percent &&
|
|
peak_memory_usage_mb <= config.max_memory_usage_mb &&
|
|
buffers_per_second >= config.min_throughput_buffers_per_sec;
|
|
}
|
|
|
|
// 打印结果
|
|
void print() const {
|
|
common::Logger::instance().info("性能测试结果: " + test_name);
|
|
common::Logger::instance().info(" 测试持续时间: " + std::to_string(test_duration.count()) + " ms");
|
|
common::Logger::instance().info(" 延迟统计 (ms):");
|
|
common::Logger::instance().info(" 最小值: " + std::to_string(min_latency_ms));
|
|
common::Logger::instance().info(" 最大值: " + std::to_string(max_latency_ms));
|
|
common::Logger::instance().info(" 平均值: " + std::to_string(avg_latency_ms));
|
|
common::Logger::instance().info(" 中位数: " + std::to_string(median_latency_ms));
|
|
common::Logger::instance().info(" 95%分位数: " + std::to_string(p95_latency_ms));
|
|
common::Logger::instance().info(" 99%分位数: " + std::to_string(p99_latency_ms));
|
|
common::Logger::instance().info(" 吞吐量:");
|
|
common::Logger::instance().info(" 总处理缓冲区数: " + std::to_string(total_buffers_processed));
|
|
common::Logger::instance().info(" 每秒缓冲区数: " + std::to_string(buffers_per_second));
|
|
common::Logger::instance().info(" 资源使用:");
|
|
common::Logger::instance().info(" 峰值CPU使用率: " + std::to_string(peak_cpu_usage_percent) + "%");
|
|
common::Logger::instance().info(" 平均CPU使用率: " + std::to_string(avg_cpu_usage_percent) + "%");
|
|
common::Logger::instance().info(" 峰值内存使用: " + std::to_string(peak_memory_usage_mb) + " MB");
|
|
}
|
|
};
|
|
|
|
// 性能基准测试类
|
|
class PerformanceBenchmarkTest : public IntegrationTest {
|
|
protected:
|
|
void SetUp() override {
|
|
IntegrationTest::SetUp();
|
|
|
|
// 初始化基准测试配置
|
|
benchmark_config_ = create_default_config();
|
|
}
|
|
|
|
void TearDown() override {
|
|
IntegrationTest::TearDown();
|
|
}
|
|
|
|
// 创建默认测试配置
|
|
PerformanceTestConfig create_default_config() {
|
|
PerformanceTestConfig config;
|
|
// 使用默认值
|
|
return config;
|
|
}
|
|
|
|
// 创建测试音频缓冲区
|
|
engine::AudioBuffer create_benchmark_buffer(
|
|
uint32_t frames = DEFAULT_BUFFER_SIZE,
|
|
uint16_t channels = DEFAULT_CHANNELS,
|
|
engine::AudioFormat format = engine::AudioFormat::FLOAT32,
|
|
bool fill_with_noise = true) {
|
|
|
|
auto buffer = create_test_audio_buffer(frames, channels, format, false);
|
|
|
|
if (fill_with_noise) {
|
|
// 填充白噪声
|
|
std::random_device rd;
|
|
std::mt19937 gen(rd());
|
|
std::uniform_real_distribution<float> dist(-0.5f, 0.5f);
|
|
|
|
float* data = buffer.interleaved_data<float>();
|
|
for (size_t i = 0; i < frames * channels; ++i) {
|
|
data[i] = dist(gen);
|
|
}
|
|
}
|
|
|
|
return buffer;
|
|
}
|
|
|
|
// 测量函数执行时间
|
|
template<typename Func>
|
|
double measure_execution_time_ms(Func&& func) {
|
|
auto start = std::chrono::high_resolution_clock::now();
|
|
func();
|
|
auto end = std::chrono::high_resolution_clock::now();
|
|
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
|
|
return duration.count() / 1000.0; // 转换为毫秒
|
|
}
|
|
};
|
|
|
|
// ================================================================================================
|
|
// 音频缓冲区性能测试
|
|
// ================================================================================================
|
|
TEST_F(PerformanceBenchmarkTest, AudioBufferPerformance) {
|
|
PerformanceTestResult result;
|
|
result.test_name = "音频缓冲区性能";
|
|
|
|
// 测试参数
|
|
const uint32_t iterations = benchmark_config_.benchmark_iterations;
|
|
std::vector<uint32_t> buffer_sizes = {256, 512, 1024, 2048, 4096};
|
|
|
|
common::Logger::instance().info("开始音频缓冲区性能测试...");
|
|
|
|
for (uint32_t buffer_size : buffer_sizes) {
|
|
common::Logger::instance().info("测试缓冲区大小: " + std::to_string(buffer_size));
|
|
|
|
// 创建测试缓冲区
|
|
engine::AudioBuffer src_buffer = create_benchmark_buffer(buffer_size);
|
|
engine::AudioBuffer dst_buffer(buffer_size, DEFAULT_CHANNELS, engine::AudioFormat::FLOAT32);
|
|
|
|
// 预热
|
|
for (uint32_t i = 0; i < benchmark_config_.warmup_iterations; ++i) {
|
|
src_buffer.copy_to(dst_buffer);
|
|
}
|
|
|
|
// 基准测试 - 缓冲区拷贝
|
|
std::vector<double> copy_latency;
|
|
for (uint32_t i = 0; i < iterations; ++i) {
|
|
double latency = measure_execution_time_ms([&]() {
|
|
src_buffer.copy_to(dst_buffer);
|
|
});
|
|
copy_latency.push_back(latency);
|
|
}
|
|
|
|
// 计算拷贝性能统计
|
|
double avg_copy_latency = std::accumulate(copy_latency.begin(), copy_latency.end(), 0.0) / copy_latency.size();
|
|
|
|
common::Logger::instance().info(" 缓冲区拷贝平均延迟: " + std::to_string(avg_copy_latency) + " ms");
|
|
|
|
// 基准测试 - 格式转换
|
|
engine::AudioBuffer float_buffer(buffer_size, DEFAULT_CHANNELS, engine::AudioFormat::FLOAT32);
|
|
engine::AudioBuffer int16_buffer(buffer_size, DEFAULT_CHANNELS, engine::AudioFormat::INT16);
|
|
|
|
std::vector<double> conversion_latency;
|
|
for (uint32_t i = 0; i < iterations; ++i) {
|
|
double latency = measure_execution_time_ms([&]() {
|
|
float_buffer.convert_to(int16_buffer);
|
|
});
|
|
conversion_latency.push_back(latency);
|
|
}
|
|
|
|
// 计算转换性能统计
|
|
double avg_conversion_latency = std::accumulate(conversion_latency.begin(), conversion_latency.end(), 0.0) /
|
|
conversion_latency.size();
|
|
|
|
common::Logger::instance().info(" 格式转换平均延迟: " + std::to_string(avg_conversion_latency) + " ms");
|
|
|
|
// 记录最大缓冲区大小的结果
|
|
if (buffer_size == 4096) {
|
|
result.latency_ms = copy_latency;
|
|
result.calculate_statistics();
|
|
result.total_buffers_processed = iterations;
|
|
|
|
// 计算每秒处理的缓冲区数
|
|
double total_time_sec = std::accumulate(copy_latency.begin(), copy_latency.end(), 0.0) / 1000.0;
|
|
result.buffers_per_second = static_cast<uint32_t>(iterations / total_time_sec);
|
|
}
|
|
}
|
|
|
|
// 记录测试持续时间
|
|
result.test_duration = std::chrono::milliseconds(100 * iterations);
|
|
|
|
// 打印结果
|
|
result.print();
|
|
|
|
// 验证性能要求
|
|
EXPECT_LE(result.p95_latency_ms, benchmark_config_.max_latency_ms);
|
|
EXPECT_GE(result.buffers_per_second, benchmark_config_.min_throughput_buffers_per_sec);
|
|
}
|
|
|
|
// ================================================================================================
|
|
// 通信性能测试
|
|
// ================================================================================================
|
|
TEST_F(PerformanceBenchmarkTest, CommunicationPerformance) {
|
|
PerformanceTestResult result;
|
|
result.test_name = "通信性能";
|
|
|
|
// 创建通信管理器
|
|
communication::CommunicationConfig server_config;
|
|
server_config.process_name = "benchmark_server";
|
|
server_config.routing_strategy = communication::RoutingStrategy::Auto;
|
|
server_config.enable_zmq = true;
|
|
server_config.enable_shm = true;
|
|
|
|
// ZeroMQ配置
|
|
communication::ZmqConfig zmq_config;
|
|
zmq_config.endpoint = "tcp://127.0.0.1:5559";
|
|
zmq_config.socket_type = ZMQ_REP;
|
|
zmq_config.bind_instead_of_connect = true;
|
|
server_config.zmq_configs.push_back(zmq_config);
|
|
|
|
// 共享内存配置
|
|
server_config.shm_config.segment_name = "benchmark_shm";
|
|
server_config.shm_config.segment_size = 1024 * 1024 * 10; // 10MB
|
|
server_config.shm_config.create_if_not_exists = true;
|
|
|
|
// 创建服务器
|
|
auto server_manager = std::make_unique<communication::CommunicationManager>(server_config);
|
|
ASSERT_EQ(server_manager->initialize(), common::ErrorCode::Success);
|
|
|
|
// 创建客户端配置
|
|
communication::CommunicationConfig client_config;
|
|
client_config.process_name = "benchmark_client";
|
|
client_config.routing_strategy = communication::RoutingStrategy::Auto;
|
|
client_config.enable_zmq = true;
|
|
client_config.enable_shm = true;
|
|
|
|
// ZeroMQ配置
|
|
communication::ZmqConfig client_zmq_config;
|
|
client_zmq_config.endpoint = "tcp://127.0.0.1:5559";
|
|
client_zmq_config.socket_type = ZMQ_REQ;
|
|
client_zmq_config.bind_instead_of_connect = false;
|
|
client_config.zmq_configs.push_back(client_zmq_config);
|
|
|
|
// 共享内存配置
|
|
client_config.shm_config.segment_name = "benchmark_shm";
|
|
client_config.shm_config.segment_size = 1024 * 1024 * 10; // 10MB
|
|
client_config.shm_config.create_if_not_exists = false;
|
|
|
|
// 创建客户端
|
|
auto client_manager = std::make_unique<communication::CommunicationManager>(client_config);
|
|
ASSERT_EQ(client_manager->initialize(), common::ErrorCode::Success);
|
|
|
|
// 创建消息工厂和注册消息类型
|
|
communication::MessageFactory message_factory;
|
|
|
|
// 注册消息处理器
|
|
server_manager->register_message_handler("BenchmarkMessage", [&](std::unique_ptr<communication::IMessage> message) {
|
|
// 直接回送相同的消息作为响应
|
|
server_manager->send_message(*message);
|
|
});
|
|
|
|
// 创建基准测试消息类
|
|
class BenchmarkMessage : public communication::Message {
|
|
public:
|
|
BenchmarkMessage(size_t payload_size = 0)
|
|
: communication::Message("BenchmarkMessage"),
|
|
payload_(payload_size, 'A') {}
|
|
|
|
size_t estimated_size() const override { return sizeof(*this) + payload_.size(); }
|
|
Priority priority() const override { return Priority::Normal; }
|
|
TransportChannel preferred_channel() const override {
|
|
return payload_.size() > 16384 ? TransportChannel::SharedMemory : TransportChannel::ZeroMQ;
|
|
}
|
|
|
|
private:
|
|
std::string payload_;
|
|
};
|
|
|
|
// 测试不同大小的消息
|
|
std::vector<size_t> message_sizes = {128, 1024, 8192, 65536, 262144, 1048576};
|
|
|
|
common::Logger::instance().info("开始通信性能测试...");
|
|
|
|
for (size_t message_size : message_sizes) {
|
|
common::Logger::instance().info("测试消息大小: " + std::to_string(message_size) + " 字节");
|
|
|
|
// 创建测试消息
|
|
BenchmarkMessage test_message(message_size);
|
|
|
|
// 预热
|
|
for (uint32_t i = 0; i < benchmark_config_.warmup_iterations; ++i) {
|
|
client_manager->send_message(test_message);
|
|
std::unique_ptr<communication::IMessage> response;
|
|
client_manager->receive_message(response, 1000);
|
|
}
|
|
|
|
// 基准测试
|
|
std::vector<double> latency;
|
|
for (uint32_t i = 0; i < benchmark_config_.benchmark_iterations; ++i) {
|
|
double round_trip_time = measure_execution_time_ms([&]() {
|
|
client_manager->send_message(test_message);
|
|
std::unique_ptr<communication::IMessage> response;
|
|
client_manager->receive_message(response, 1000);
|
|
});
|
|
|
|
latency.push_back(round_trip_time);
|
|
}
|
|
|
|
// 计算统计
|
|
double avg_latency = std::accumulate(latency.begin(), latency.end(), 0.0) / latency.size();
|
|
double min_latency = *std::min_element(latency.begin(), latency.end());
|
|
double max_latency = *std::max_element(latency.begin(), latency.end());
|
|
|
|
common::Logger::instance().info(" 平均往返延迟: " + std::to_string(avg_latency) + " ms");
|
|
common::Logger::instance().info(" 最小往返延迟: " + std::to_string(min_latency) + " ms");
|
|
common::Logger::instance().info(" 最大往返延迟: " + std::to_string(max_latency) + " ms");
|
|
|
|
// 记录中等大小消息的结果
|
|
if (message_size == 8192) {
|
|
result.latency_ms = latency;
|
|
result.calculate_statistics();
|
|
result.total_buffers_processed = benchmark_config_.benchmark_iterations;
|
|
|
|
// 计算每秒处理的消息数
|
|
double total_time_sec = std::accumulate(latency.begin(), latency.end(), 0.0) / 1000.0;
|
|
result.buffers_per_second = static_cast<uint32_t>(benchmark_config_.benchmark_iterations / total_time_sec);
|
|
}
|
|
}
|
|
|
|
// 记录测试持续时间
|
|
result.test_duration = std::chrono::milliseconds(
|
|
benchmark_config_.benchmark_iterations * message_sizes.size() * 10); // 粗略估计
|
|
|
|
// 关闭通信管理器
|
|
client_manager->shutdown();
|
|
server_manager->shutdown();
|
|
|
|
// 打印结果
|
|
result.print();
|
|
|
|
// 验证性能要求
|
|
EXPECT_LE(result.p95_latency_ms, benchmark_config_.max_latency_ms * 2); // 往返通信允许更高延迟
|
|
EXPECT_GE(result.buffers_per_second, benchmark_config_.min_throughput_buffers_per_sec / 2);
|
|
}
|
|
|
|
// ================================================================================================
|
|
// 音频处理性能测试
|
|
// ================================================================================================
|
|
TEST_F(PerformanceBenchmarkTest, AudioProcessingPerformance) {
|
|
PerformanceTestResult result;
|
|
result.test_name = "音频处理性能";
|
|
|
|
// 创建音频处理函数
|
|
auto apply_gain = [](engine::AudioBuffer& buffer, float gain) {
|
|
if (buffer.format() != engine::AudioFormat::FLOAT32) {
|
|
return;
|
|
}
|
|
|
|
float* data = buffer.interleaved_data<float>();
|
|
for (size_t i = 0; i < buffer.num_frames() * buffer.num_channels(); ++i) {
|
|
data[i] *= gain;
|
|
}
|
|
};
|
|
|
|
auto apply_lowpass_filter = [](engine::AudioBuffer& buffer, float cutoff) {
|
|
if (buffer.format() != engine::AudioFormat::FLOAT32) {
|
|
return;
|
|
}
|
|
|
|
// 简单IIR低通滤波器
|
|
float* data = buffer.interleaved_data<float>();
|
|
size_t channels = buffer.num_channels();
|
|
size_t frames = buffer.num_frames();
|
|
|
|
// 滤波器系数 (简化的一阶低通)
|
|
float a = cutoff;
|
|
|
|
// 应用滤波器
|
|
std::vector<float> prev(channels, 0.0f);
|
|
|
|
for (size_t i = 0; i < frames; ++i) {
|
|
for (size_t c = 0; c < channels; ++c) {
|
|
size_t idx = i * channels + c;
|
|
float current = data[idx];
|
|
float filtered = prev[c] + a * (current - prev[c]);
|
|
data[idx] = filtered;
|
|
prev[c] = filtered;
|
|
}
|
|
}
|
|
};
|
|
|
|
// 测试不同的处理链
|
|
std::vector<std::pair<std::string, std::function<void(engine::AudioBuffer&)>>> processing_chains = {
|
|
{"增益调整", [&](engine::AudioBuffer& buffer) {
|
|
apply_gain(buffer, 0.8f);
|
|
}},
|
|
{"低通滤波", [&](engine::AudioBuffer& buffer) {
|
|
apply_lowpass_filter(buffer, 0.1f);
|
|
}},
|
|
{"增益+低通滤波", [&](engine::AudioBuffer& buffer) {
|
|
apply_gain(buffer, 0.8f);
|
|
apply_lowpass_filter(buffer, 0.1f);
|
|
}}
|
|
};
|
|
|
|
common::Logger::instance().info("开始音频处理性能测试...");
|
|
|
|
for (const auto& [name, processor] : processing_chains) {
|
|
common::Logger::instance().info("测试处理链: " + name);
|
|
|
|
// 创建测试缓冲区
|
|
auto buffer = create_benchmark_buffer(benchmark_config_.buffer_size);
|
|
|
|
// 预热
|
|
for (uint32_t i = 0; i < benchmark_config_.warmup_iterations; ++i) {
|
|
processor(buffer);
|
|
}
|
|
|
|
// 基准测试
|
|
std::vector<double> latency;
|
|
for (uint32_t i = 0; i < benchmark_config_.benchmark_iterations; ++i) {
|
|
double processing_time = measure_execution_time_ms([&]() {
|
|
processor(buffer);
|
|
});
|
|
latency.push_back(processing_time);
|
|
}
|
|
|
|
// 计算统计
|
|
double avg_latency = std::accumulate(latency.begin(), latency.end(), 0.0) / latency.size();
|
|
double min_latency = *std::min_element(latency.begin(), latency.end());
|
|
double max_latency = *std::max_element(latency.begin(), latency.end());
|
|
|
|
common::Logger::instance().info(" 平均处理延迟: " + std::to_string(avg_latency) + " ms");
|
|
common::Logger::instance().info(" 最小处理延迟: " + std::to_string(min_latency) + " ms");
|
|
common::Logger::instance().info(" 最大处理延迟: " + std::to_string(max_latency) + " ms");
|
|
|
|
// 计算每秒可处理的缓冲区数
|
|
double buffers_per_second = 1000.0 / avg_latency;
|
|
common::Logger::instance().info(" 每秒可处理缓冲区数: " + std::to_string(buffers_per_second));
|
|
|
|
// 记录最复杂处理链的结果
|
|
if (name == "增益+低通滤波") {
|
|
result.latency_ms = latency;
|
|
result.calculate_statistics();
|
|
result.total_buffers_processed = benchmark_config_.benchmark_iterations;
|
|
result.buffers_per_second = static_cast<uint32_t>(buffers_per_second);
|
|
}
|
|
}
|
|
|
|
// 记录测试持续时间
|
|
result.test_duration = std::chrono::milliseconds(
|
|
benchmark_config_.benchmark_iterations * processing_chains.size() * 10); // 粗略估计
|
|
|
|
// 打印结果
|
|
result.print();
|
|
|
|
// 验证性能要求
|
|
EXPECT_LE(result.p95_latency_ms, benchmark_config_.max_latency_ms / 2); // 单一处理应该非常快
|
|
EXPECT_GE(result.buffers_per_second, benchmark_config_.min_throughput_buffers_per_sec * 2);
|
|
}
|
|
|
|
// ================================================================================================
|
|
// 系统吞吐量测试
|
|
// ================================================================================================
|
|
TEST_F(PerformanceBenchmarkTest, SystemThroughputTest) {
|
|
PerformanceTestResult result;
|
|
result.test_name = "系统吞吐量";
|
|
|
|
// 创建通信管理器
|
|
communication::CommunicationConfig server_config;
|
|
server_config.process_name = "throughput_server";
|
|
server_config.routing_strategy = communication::RoutingStrategy::Auto;
|
|
server_config.enable_zmq = true;
|
|
server_config.enable_shm = true;
|
|
|
|
// ZeroMQ配置
|
|
communication::ZmqConfig zmq_config;
|
|
zmq_config.endpoint = "tcp://127.0.0.1:5560";
|
|
zmq_config.socket_type = ZMQ_PULL;
|
|
zmq_config.bind_instead_of_connect = true;
|
|
server_config.zmq_configs.push_back(zmq_config);
|
|
|
|
// 创建服务器
|
|
auto server_manager = std::make_unique<communication::CommunicationManager>(server_config);
|
|
ASSERT_EQ(server_manager->initialize(), common::ErrorCode::Success);
|
|
|
|
// 创建客户端配置
|
|
communication::CommunicationConfig client_config;
|
|
client_config.process_name = "throughput_client";
|
|
client_config.routing_strategy = communication::RoutingStrategy::Auto;
|
|
client_config.enable_zmq = true;
|
|
|
|
// ZeroMQ配置
|
|
communication::ZmqConfig client_zmq_config;
|
|
client_zmq_config.endpoint = "tcp://127.0.0.1:5560";
|
|
client_zmq_config.socket_type = ZMQ_PUSH;
|
|
client_zmq_config.bind_instead_of_connect = false;
|
|
client_config.zmq_configs.push_back(client_zmq_config);
|
|
|
|
// 创建客户端
|
|
auto client_manager = std::make_unique<communication::CommunicationManager>(client_config);
|
|
ASSERT_EQ(client_manager->initialize(), common::ErrorCode::Success);
|
|
|
|
// 创建消息计数器和同步原语
|
|
std::atomic<uint32_t> messages_received{0};
|
|
std::atomic<bool> test_running{true};
|
|
std::mutex mutex;
|
|
std::condition_variable cv;
|
|
|
|
// 注册消息处理器
|
|
server_manager->register_message_handler("ThroughputMessage", [&](std::unique_ptr<communication::IMessage> message) {
|
|
messages_received++;
|
|
});
|
|
|
|
// 创建吞吐量测试消息类
|
|
class ThroughputMessage : public communication::Message {
|
|
public:
|
|
ThroughputMessage(uint32_t size = 1024)
|
|
: communication::Message("ThroughputMessage"),
|
|
payload_(size, 'T') {}
|
|
|
|
size_t estimated_size() const override { return sizeof(*this) + payload_.size(); }
|
|
Priority priority() const override { return Priority::Normal; }
|
|
TransportChannel preferred_channel() const override { return TransportChannel::ZeroMQ; }
|
|
|
|
private:
|
|
std::string payload_;
|
|
};
|
|
|
|
// 创建测试消息
|
|
ThroughputMessage test_message(1024);
|
|
|
|
// 启动接收线程
|
|
std::thread receiver_thread([&]() {
|
|
while (test_running.load()) {
|
|
std::this_thread::sleep_for(100ms);
|
|
}
|
|
cv.notify_one();
|
|
});
|
|
|
|
common::Logger::instance().info("开始系统吞吐量测试...");
|
|
|
|
// 记录开始时间
|
|
auto start_time = std::chrono::high_resolution_clock::now();
|
|
|
|
// 测试持续时间
|
|
std::chrono::milliseconds test_duration(benchmark_config_.stress_test_duration_ms);
|
|
|
|
// 发送消息
|
|
std::vector<std::thread> sender_threads;
|
|
std::atomic<uint32_t> messages_sent{0};
|
|
|
|
for (uint32_t i = 0; i < benchmark_config_.concurrency_level; ++i) {
|
|
sender_threads.emplace_back([&]() {
|
|
while (true) {
|
|
auto now = std::chrono::high_resolution_clock::now();
|
|
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time);
|
|
|
|
if (elapsed >= test_duration) {
|
|
break;
|
|
}
|
|
|
|
client_manager->send_message(test_message);
|
|
messages_sent++;
|
|
}
|
|
});
|
|
}
|
|
|
|
// 等待测试完成
|
|
for (auto& thread : sender_threads) {
|
|
thread.join();
|
|
}
|
|
|
|
// 停止接收线程
|
|
test_running = false;
|
|
{
|
|
std::unique_lock<std::mutex> lock(mutex);
|
|
cv.wait_for(lock, 1s);
|
|
}
|
|
receiver_thread.join();
|
|
|
|
// 记录结束时间
|
|
auto end_time = std::chrono::high_resolution_clock::now();
|
|
auto actual_duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
|
|
|
|
// 计算吞吐量
|
|
uint32_t total_sent = messages_sent.load();
|
|
uint32_t total_received = messages_received.load();
|
|
double seconds = actual_duration.count() / 1000.0;
|
|
uint32_t msgs_per_second = static_cast<uint32_t>(total_sent / seconds);
|
|
|
|
common::Logger::instance().info("吞吐量测试结果:");
|
|
common::Logger::instance().info(" 测试持续时间: " + std::to_string(actual_duration.count()) + " ms");
|
|
common::Logger::instance().info(" 发送消息数: " + std::to_string(total_sent));
|
|
common::Logger::instance().info(" 接收消息数: " + std::to_string(total_received));
|
|
common::Logger::instance().info(" 每秒消息数: " + std::to_string(msgs_per_second));
|
|
|
|
// 记录结果
|
|
result.total_buffers_processed = total_sent;
|
|
result.buffers_per_second = msgs_per_second;
|
|
result.test_duration = actual_duration;
|
|
|
|
// 关闭通信管理器
|
|
client_manager->shutdown();
|
|
server_manager->shutdown();
|
|
|
|
// 打印结果
|
|
result.print();
|
|
|
|
// 验证性能要求
|
|
EXPECT_GE(result.buffers_per_second, benchmark_config_.min_throughput_buffers_per_sec * 10);
|
|
}
|
|
|
|
int main(int argc, char** argv) {
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
return RUN_ALL_TESTS();
|
|
} |