From d589de67c263f723a5610670488f2d05adafad19 Mon Sep 17 00:00:00 2001 From: Jinyang Su <751080330@qq.com> Date: Wed, 2 Jul 2025 10:32:36 +0800 Subject: [PATCH 1/2] Disable memcpy by default and improve stress workload test - Set MC_STORE_MEMCPY default to false for more stable RDMA performance - Rewrite stress_workload_test.cpp as standalone benchmark with separate PUT/GET throughput calculations - Add comprehensive performance metrics including latency percentiles and operation-specific throughput - Replace gtest dependency with gflags for better configuration flexibility --- mooncake-store/src/transfer_task.cpp | 4 +- mooncake-store/tests/CMakeLists.txt | 5 +- mooncake-store/tests/stress_workload_test.cpp | 536 ++++++++++++------ 3 files changed, 367 insertions(+), 178 deletions(-) diff --git a/mooncake-store/src/transfer_task.cpp b/mooncake-store/src/transfer_task.cpp index 7106421af9..a380784fa2 100644 --- a/mooncake-store/src/transfer_task.cpp +++ b/mooncake-store/src/transfer_task.cpp @@ -251,10 +251,10 @@ TransferSubmitter::TransferSubmitter(TransferEngine& engine, memcpy_pool_(std::make_unique()) { CHECK(!local_hostname_.empty()) << "Local hostname cannot be empty"; - // Read MC_STORE_MEMCPY environment variable, default to true (enabled) + // Read MC_STORE_MEMCPY environment variable, default to false (disabled) const char* env_value = std::getenv("MC_STORE_MEMCPY"); if (env_value == nullptr) { - memcpy_enabled_ = true; // Default: enabled + memcpy_enabled_ = false; // Default: disabled } else { std::string env_str(env_value); // Convert to lowercase for case-insensitive comparison diff --git a/mooncake-store/tests/CMakeLists.txt b/mooncake-store/tests/CMakeLists.txt index 48c443911d..31b0b2b8fa 100644 --- a/mooncake-store/tests/CMakeLists.txt +++ b/mooncake-store/tests/CMakeLists.txt @@ -42,8 +42,7 @@ target_link_libraries(stress_workload_test PUBLIC cachelib_memory_allocator ${ETCD_WRAPPER_LIB} glog - gtest - gtest_main + gflags pthread ) @@ -69,4 +68,4 @@ target_link_libraries(segment_test PUBLIC ) add_test(NAME segment_test COMMAND segment_test) -add_subdirectory(e2e) \ No newline at end of file +add_subdirectory(e2e) diff --git a/mooncake-store/tests/stress_workload_test.cpp b/mooncake-store/tests/stress_workload_test.cpp index 93d2799e94..8e8856243b 100644 --- a/mooncake-store/tests/stress_workload_test.cpp +++ b/mooncake-store/tests/stress_workload_test.cpp @@ -1,11 +1,13 @@ #include #include -#include #include +#include +#include +#include #include -#include #include +#include #include #include "allocator.h" @@ -13,213 +15,401 @@ #include "types.h" #include "utils.h" +// Configuration flags DEFINE_string(protocol, "rdma", "Transfer protocol: rdma|tcp"); -DEFINE_string(device_name, "ibp6s0", +DEFINE_string(device_name, "erdma_0", "Device name to use, valid if protocol=rdma"); DEFINE_string(master_address, "localhost:50051", "Address of master server"); +DEFINE_int32(num_threads, 8, "Number of concurrent worker threads"); +DEFINE_int32(test_operation_nums, 100, "Number of operations per thread"); +DEFINE_int32(key_size, 128, "Size of keys in bytes"); +DEFINE_int32(value_size, 1048576, "Size of values in bytes (default: 1MB)"); + +// Memory configuration flags +DEFINE_uint64(ram_buffer_size_gb, 15, + "RAM buffer size in GB for segment allocation"); +DEFINE_uint64(client_buffer_allocator_size_mb, 256, + "Client buffer allocator size in MB"); + +// Network configuration flags +DEFINE_string(local_hostname, "localhost:12345", "Local hostname for client"); +DEFINE_string(metadata_connection_string, "P2PHANDSHAKE", + "Metadata connection string"); namespace mooncake { -namespace testing { - -class RandomGen { - public: - std::random_device req_rd; - std::vector random_key; - std::vector random_value; - int max_len; - int max_key_size; - int max_value_size; - bool use_skew; - long long ran_counter; - const std::string characters = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789"; - RandomGen(int max_len_, int max_key_size_, int max_value_size_) - : max_len(max_len_), - max_key_size(max_key_size_), - max_value_size(max_value_size_), - ran_counter(0) { - uniform(); - } - ~RandomGen() {} - - void skew() { - // not implement - } - - std::string generateRandomString(size_t length) { - std::string randomString; - size_t charactersCount = characters.size(); - - for (size_t i = 0; i < length; ++i) { - // Generate a random index - size_t randomIndex = req_rd() % charactersCount; - // Append the character at the random index to the random string - randomString += characters[randomIndex]; - } +namespace benchmark { + +// Global client and allocator instances +std::shared_ptr g_client = nullptr; +std::unique_ptr g_client_buffer_allocator = nullptr; +void* g_segment_ptr = nullptr; +size_t g_ram_buffer_size = 0; + +// Performance measurement structures +struct OperationResult { + double latency_us; // Latency in microseconds + bool is_put; // true for PUT, false for GET + bool success; // Operation success status +}; + +struct ThreadStats { + std::vector operations; + uint64_t total_operations = 0; + uint64_t successful_operations = 0; + uint64_t put_operations = 0; + uint64_t get_operations = 0; +}; + +bool initialize_segment() { + // Use gflags configuration for RAM buffer size + g_ram_buffer_size = FLAGS_ram_buffer_size_gb * 1024ull * 1024 * 1024; + g_segment_ptr = allocate_buffer_allocator_memory(g_ram_buffer_size); + if (!g_segment_ptr) { + LOG(ERROR) << "Failed to allocate segment memory of size " + << FLAGS_ram_buffer_size_gb << "GB"; + return false; + } - return randomString; + ErrorCode rc = g_client->MountSegment(g_segment_ptr, g_ram_buffer_size); + if (rc != ErrorCode::OK) { + LOG(ERROR) << "Failed to mount segment: " << toString(rc); + return false; } - void uniform() { - for (int i = 0; i < max_len; i++) { - random_key.push_back(generateRandomString(max_key_size)); - std::string value; - value.resize(max_value_size, - characters[req_rd() % characters.size()]); - random_value.push_back(value); + LOG(INFO) << "Segment initialized successfully with " + << FLAGS_ram_buffer_size_gb << "GB RAM buffer"; + return true; +} + +void cleanup_segment() { + if (g_segment_ptr && g_client) { + ErrorCode rc = + g_client->UnmountSegment(g_segment_ptr, g_ram_buffer_size); + if (rc != ErrorCode::OK) { + LOG(ERROR) << "Failed to unmount segment: " << toString(rc); } } +} + +bool initialize_client() { + void** args = + (FLAGS_protocol == "rdma") ? rdma_args(FLAGS_device_name) : nullptr; - std::pair get_pair() { - ran_counter++; - ran_counter %= max_len; - return {random_key[ran_counter], random_value[ran_counter]}; + auto client_opt = Client::Create( + FLAGS_local_hostname, // Local hostname + FLAGS_metadata_connection_string, // Metadata connection string + FLAGS_protocol, args, FLAGS_master_address); + + if (!client_opt.has_value()) { + LOG(ERROR) << "Failed to create client"; + return false; } - std::string get_key() { - ran_counter++; - ran_counter %= max_len; - return random_key[ran_counter]; + LOG(INFO) << "Create client successfully"; + + g_client = *client_opt; + + // Use gflags configuration for client buffer allocator size + auto client_buffer_allocator_size = + FLAGS_client_buffer_allocator_size_mb * 1024 * 1024; + g_client_buffer_allocator = + std::make_unique(client_buffer_allocator_size); + + ErrorCode error_code = g_client->RegisterLocalMemory( + g_client_buffer_allocator->getBase(), client_buffer_allocator_size, + "cpu:0", false, false); + + if (error_code != ErrorCode::OK) { + LOG(ERROR) << "Failed to register local memory: " + << toString(error_code); + return false; } - std::string get_value() { - ran_counter++; - ran_counter %= max_len; - return random_value[ran_counter]; + + // Verify that the buffer allocator has enough space for all threads + size_t total_required_memory = FLAGS_num_threads * FLAGS_value_size; + if (total_required_memory > client_buffer_allocator_size) { + LOG(ERROR) << "Insufficient buffer allocator memory. Required: " + << total_required_memory / (1024 * 1024) + << "MB, Available: " << FLAGS_client_buffer_allocator_size_mb + << "MB"; + return false; } -}; -class ClientIntegrationTest : public ::testing::Test { - protected: - static void SetUpTestSuite() { - // Initialize glog - google::InitGoogleLogging("ClientIntegrationTest"); - FLAGS_logtostderr = 1; + LOG(INFO) << "Client initialized successfully with " + << FLAGS_client_buffer_allocator_size_mb << "MB buffer allocator"; + return true; +} - LOG(INFO) << "Protocol: " << FLAGS_protocol - << ", Device name: " << FLAGS_device_name; - InitializeClient(); - InitializeSegment(); +void cleanup_client() { + if (g_client) { + g_client.reset(); } + g_client_buffer_allocator.reset(); +} - static void TearDownTestSuite() { - // Cleanup client, server, and master components - CleanupSegment(); - CleanupClient(); +std::string generate_key(int thread_id, uint64_t operation_id) { + return "key_" + std::to_string(thread_id) + "_" + + std::to_string(operation_id); +} - google::ShutdownGoogleLogging(); +void worker_thread(int thread_id, std::atomic& stop_flag, + ThreadStats& stats) { + // Allocate thread-local buffer + void* write_buffer = g_client_buffer_allocator->allocate(FLAGS_value_size); + if (!write_buffer) { + LOG(ERROR) << "Thread " << thread_id + << ": Failed to allocate write buffer"; + return; } - static void InitializeSegment() { - ram_buffer_size_ = 3200ull * 1024 * 1024; - segment_ptr_ = allocate_buffer_allocator_memory(ram_buffer_size_); - ASSERT_TRUE(segment_ptr_); - ErrorCode rc = client_->MountSegment(segment_ptr_, - ram_buffer_size_); - if (rc != ErrorCode::OK) { - LOG(ERROR) << "Failed to mount segment: " << toString(rc); - } - } + // Fill buffer with simple pattern + memset(write_buffer, 'A' + (thread_id % 26), FLAGS_value_size); + + std::vector slices; + slices.emplace_back( + Slice{write_buffer, static_cast(FLAGS_value_size)}); + + ReplicateConfig config; + config.replica_num = 1; - static void CleanupSegment() { - if (client_->UnmountSegment(segment_ptr_, ram_buffer_size_) != - ErrorCode::OK) { - LOG(ERROR) << "Failed to unmount segment"; + std::vector stored_keys; // Track keys for GET operations + + // Phase 1: Perform PUT operations + for (int i = 0; i < FLAGS_test_operation_nums && !stop_flag.load(); ++i) { + std::string key = generate_key(thread_id, i); + + auto start_time = std::chrono::high_resolution_clock::now(); + ErrorCode result = g_client->Put(key.data(), slices, config); + auto end_time = std::chrono::high_resolution_clock::now(); + + auto latency_us = std::chrono::duration_cast( + end_time - start_time) + .count(); + + bool success = (result == ErrorCode::OK); + stats.operations.push_back( + {static_cast(latency_us), true, success}); + + if (success) { + stored_keys.push_back(key); + stats.put_operations++; + stats.successful_operations++; } + + stats.total_operations++; } - static void InitializeClient() { - void** args = - (FLAGS_protocol == "rdma") ? rdma_args(FLAGS_device_name) : nullptr; + // Phase 2: Perform GET operations on the stored keys + for (int i = 0; i < FLAGS_test_operation_nums && !stop_flag.load() && + !stored_keys.empty(); + ++i) { + // Use modulo to cycle through stored keys deterministically + size_t key_index = i % stored_keys.size(); + std::string key = stored_keys[key_index]; + + auto start_time = std::chrono::high_resolution_clock::now(); + ErrorCode result = g_client->Get(key.data(), slices); + auto end_time = std::chrono::high_resolution_clock::now(); - auto client_opt = - Client::Create("localhost:12345", // Local hostname - "127.0.0.1:2379", // Metadata connection string - FLAGS_protocol, args, FLAGS_master_address); + auto latency_us = std::chrono::duration_cast( + end_time - start_time) + .count(); - ASSERT_TRUE(client_opt.has_value()) << "Failed to create client"; - client_ = *client_opt; + bool success = (result == ErrorCode::OK); + stats.operations.push_back( + {static_cast(latency_us), false, success}); - auto client_buffer_allocator_size = 128 * 1024 * 1024; - client_buffer_allocator_ = - std::make_unique(client_buffer_allocator_size); - ErrorCode error_code = client_->RegisterLocalMemory( - client_buffer_allocator_->getBase(), client_buffer_allocator_size, - "cpu:0", false, false); - if (error_code != ErrorCode::OK) { - LOG(ERROR) << "Failed to allocate transfer buffer: " - << toString(error_code); + if (success) { + stats.get_operations++; + stats.successful_operations++; } + + stats.total_operations++; } - static void CleanupClient() { - if (client_) { - client_.reset(); - } + g_client_buffer_allocator->deallocate(write_buffer, FLAGS_value_size); +} + +void calculate_percentiles(std::vector& latencies, double& p50, + double& p90, double& p95, double& p99) { + if (latencies.empty()) { + p50 = p90 = p95 = p99 = 0.0; + return; } - static std::shared_ptr client_; - static std::unique_ptr client_buffer_allocator_; - static void* segment_ptr_; - static size_t ram_buffer_size_; -}; + std::sort(latencies.begin(), latencies.end()); + size_t size = latencies.size(); + + // Use explicit parentheses and floating-point arithmetic for safe + // percentile calculation This avoids integer division order issues and + // ensures correct indices + p50 = latencies[static_cast(size * 0.50)]; + p90 = latencies[static_cast(size * 0.90)]; + p95 = latencies[static_cast(size * 0.95)]; + p99 = latencies[static_cast(size * 0.99)]; +} -// Static members initialization -std::shared_ptr ClientIntegrationTest::client_ = nullptr; -void* ClientIntegrationTest::segment_ptr_ = nullptr; -std::unique_ptr - ClientIntegrationTest::client_buffer_allocator_ = nullptr; -size_t ClientIntegrationTest::ram_buffer_size_ = 0; - -// Test basic Put/Get operations through the client -TEST_F(ClientIntegrationTest, StressPutOperations) { - const static int kThreads = 8; - pthread_barrier_t barrier; - pthread_barrier_init(&barrier, nullptr, kThreads + 1); - std::vector runner_list; - const int rand_len = 100; - const int value_length = kMaxSliceSize; - - for (int i = 0; i < kThreads; ++i) { - runner_list.push_back(std::thread([&]() { - RandomGen rand_gen(rand_len, 128, value_length); - - // Test Put operation - ReplicateConfig config; - config.replica_num = 1; - - void* write_buffer = - client_buffer_allocator_->allocate(value_length); - std::vector slices; - slices.emplace_back(Slice{write_buffer, value_length}); - pthread_barrier_wait(&barrier); - for (int i = 0; i < rand_len; i++) { - auto entry = rand_gen.get_pair(); - memcpy(write_buffer, entry.second.data(), entry.second.size()); - slices[0].size = entry.second.size(); - ASSERT_EQ(client_->Put(entry.first.data(), slices, config), - ErrorCode::OK); - ASSERT_EQ(client_->Get(entry.first.data(), slices), - ErrorCode::OK); - ASSERT_EQ(client_->Remove(entry.first.data()), ErrorCode::OK); +void print_results(const std::vector& thread_stats, + double duration_s) { + // Aggregate statistics + uint64_t total_ops = 0; + uint64_t successful_ops = 0; + uint64_t total_put_ops = 0; + uint64_t total_get_ops = 0; + + std::vector all_latencies; + std::vector put_latencies; + std::vector get_latencies; + + for (const auto& stats : thread_stats) { + total_ops += stats.total_operations; + successful_ops += stats.successful_operations; + total_put_ops += stats.put_operations; + total_get_ops += stats.get_operations; + + for (const auto& op : stats.operations) { + if (op.success) { + all_latencies.push_back(op.latency_us); + if (op.is_put) { + put_latencies.push_back(op.latency_us); + } else { + get_latencies.push_back(op.latency_us); + } } - pthread_barrier_wait(&barrier); - client_buffer_allocator_->deallocate(write_buffer, value_length); - })); - } - - LOG(INFO) << "Begin testing"; - pthread_barrier_wait(&barrier); - auto start_ts = getCurrentTimeInNano(); - pthread_barrier_wait(&barrier); - auto end_ts = getCurrentTimeInNano(); - auto duration_ms = (end_ts - start_ts) / 1000000.0; - LOG(INFO) << "duration/ms: " << duration_ms << " throughput/kB/s: " - << 2 * value_length * 1.00 * rand_len * kThreads / duration_ms; - for (auto& runner : runner_list) runner.join(); - runner_list.clear(); + } + } + + // Calculate percentiles + double all_p50, all_p90, all_p95, all_p99; + double put_p50, put_p90, put_p95, put_p99; + double get_p50, get_p90, get_p95, get_p99; + + calculate_percentiles(all_latencies, all_p50, all_p90, all_p95, all_p99); + calculate_percentiles(put_latencies, put_p50, put_p90, put_p95, put_p99); + calculate_percentiles(get_latencies, get_p50, get_p90, get_p95, get_p99); + + // Calculate throughput + double ops_per_second = successful_ops / duration_s; + double put_ops_per_second = total_put_ops / duration_s; + double get_ops_per_second = total_get_ops / duration_s; + + // Calculate data throughput separately for PUT and GET operations + double put_data_throughput_mb_s = + (total_put_ops * FLAGS_value_size) / (duration_s * 1024 * 1024); + double get_data_throughput_mb_s = + (total_get_ops * FLAGS_value_size) / (duration_s * 1024 * 1024); + double total_data_throughput_mb_s = + put_data_throughput_mb_s + get_data_throughput_mb_s; + + // Print results + LOG(INFO) << "=== Benchmark Results ==="; + LOG(INFO) << "Test Duration: " << duration_s << " seconds"; + LOG(INFO) << "Threads: " << FLAGS_num_threads; + LOG(INFO) << "Key Size: " << FLAGS_key_size << " bytes"; + LOG(INFO) << "Value Size: " << FLAGS_value_size << " bytes"; + LOG(INFO) << "Operations per thread: " << FLAGS_test_operation_nums; + LOG(INFO) << ""; + LOG(INFO) << "=== Operation Statistics ==="; + LOG(INFO) << "Total Operations: " << total_ops; + LOG(INFO) << "Successful Operations: " << successful_ops; + LOG(INFO) << "PUT Operations: " << total_put_ops; + LOG(INFO) << "GET Operations: " << total_get_ops; + LOG(INFO) << "Success Rate: " << (100.0 * successful_ops / total_ops) + << "%"; + LOG(INFO) << ""; + LOG(INFO) << "=== Throughput ==="; + LOG(INFO) << "Total Operations/sec: " << ops_per_second; + LOG(INFO) << "PUT Operations/sec: " << put_ops_per_second; + LOG(INFO) << "GET Operations/sec: " << get_ops_per_second; + LOG(INFO) << "Total Data Throughput (MB/s): " << total_data_throughput_mb_s; + LOG(INFO) << "PUT Data Throughput (MB/s): " << put_data_throughput_mb_s; + LOG(INFO) << "GET Data Throughput (MB/s): " << get_data_throughput_mb_s; + LOG(INFO) << ""; + LOG(INFO) << "=== Latency (microseconds) ==="; + LOG(INFO) << "All Operations - P50: " << all_p50 << ", P90: " << all_p90 + << ", P95: " << all_p95 << ", P99: " << all_p99; + + if (!put_latencies.empty()) { + LOG(INFO) << "PUT Operations - P50: " << put_p50 << ", P90: " << put_p90 + << ", P95: " << put_p95 << ", P99: " << put_p99; + } + + if (!get_latencies.empty()) { + LOG(INFO) << "GET Operations - P50: " << get_p50 << ", P90: " << get_p90 + << ", P95: " << get_p95 << ", P99: " << get_p99; + } } -} // namespace testing +} // namespace benchmark } // namespace mooncake + +int main(int argc, char** argv) { + // Initialize gflags and glog + gflags::ParseCommandLineFlags(&argc, &argv, true); + google::InitGoogleLogging(argv[0]); + FLAGS_logtostderr = 1; + + using namespace mooncake::benchmark; + + LOG(INFO) << "Starting Mooncake Store Stress Benchmark"; + LOG(INFO) << "Protocol: " << FLAGS_protocol + << ", Device: " << FLAGS_device_name; + LOG(INFO) << "Local hostname: " << FLAGS_local_hostname; + LOG(INFO) << "Metadata connection: " << FLAGS_metadata_connection_string; + LOG(INFO) << "Operations per thread: " << FLAGS_test_operation_nums; + LOG(INFO) << "RAM buffer size: " << FLAGS_ram_buffer_size_gb << "GB"; + LOG(INFO) << "Client buffer allocator size: " + << FLAGS_client_buffer_allocator_size_mb << "MB"; + + // Initialize client and segment + if (!initialize_client()) { + LOG(ERROR) << "Failed to initialize client"; + return 1; + } + + if (!initialize_segment()) { + LOG(ERROR) << "Failed to initialize segment"; + cleanup_client(); + return 1; + } + + // Prepare worker threads + std::vector workers; + std::vector thread_stats(FLAGS_num_threads); + std::atomic stop_flag{false}; + + LOG(INFO) << "Starting " << FLAGS_num_threads << " worker threads with " + << FLAGS_test_operation_nums << " operations each"; + + // Start worker threads + auto start_time = std::chrono::high_resolution_clock::now(); + + for (int i = 0; i < FLAGS_num_threads; ++i) { + workers.emplace_back(worker_thread, i, std::ref(stop_flag), + std::ref(thread_stats[i])); + } + + // Wait for all threads to complete (they will finish after completing their + // operations) + for (auto& worker : workers) { + worker.join(); + } + + auto end_time = std::chrono::high_resolution_clock::now(); + double actual_duration_s = + std::chrono::duration_cast(end_time - + start_time) + .count() / + 1000.0; + + // Print results + print_results(thread_stats, actual_duration_s); + + // Cleanup + cleanup_segment(); + cleanup_client(); + google::ShutdownGoogleLogging(); + + LOG(INFO) << "Benchmark completed successfully"; + return 0; +} From a82decf4b445ebd492b18fba15a7aade36781480 Mon Sep 17 00:00:00 2001 From: Jinyang Su <751080330@qq.com> Date: Wed, 2 Jul 2025 10:41:22 +0800 Subject: [PATCH 2/2] fix comments --- mooncake-store/tests/stress_workload_test.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/mooncake-store/tests/stress_workload_test.cpp b/mooncake-store/tests/stress_workload_test.cpp index 8e8856243b..4328f891d6 100644 --- a/mooncake-store/tests/stress_workload_test.cpp +++ b/mooncake-store/tests/stress_workload_test.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -22,7 +23,7 @@ DEFINE_string(device_name, "erdma_0", DEFINE_string(master_address, "localhost:50051", "Address of master server"); DEFINE_int32(num_threads, 8, "Number of concurrent worker threads"); DEFINE_int32(test_operation_nums, 100, "Number of operations per thread"); -DEFINE_int32(key_size, 128, "Size of keys in bytes"); + DEFINE_int32(value_size, 1048576, "Size of values in bytes (default: 1MB)"); // Memory configuration flags @@ -243,10 +244,10 @@ void calculate_percentiles(std::vector& latencies, double& p50, // Use explicit parentheses and floating-point arithmetic for safe // percentile calculation This avoids integer division order issues and // ensures correct indices - p50 = latencies[static_cast(size * 0.50)]; - p90 = latencies[static_cast(size * 0.90)]; - p95 = latencies[static_cast(size * 0.95)]; - p99 = latencies[static_cast(size * 0.99)]; + p50 = latencies[static_cast(std::ceil((size * 0.50) - 1))]; + p90 = latencies[static_cast(std::ceil((size * 0.90) - 1))]; + p95 = latencies[static_cast(std::ceil((size * 0.95) - 1))]; + p99 = latencies[static_cast(std::ceil((size * 0.99) - 1))]; } void print_results(const std::vector& thread_stats, @@ -305,7 +306,7 @@ void print_results(const std::vector& thread_stats, LOG(INFO) << "=== Benchmark Results ==="; LOG(INFO) << "Test Duration: " << duration_s << " seconds"; LOG(INFO) << "Threads: " << FLAGS_num_threads; - LOG(INFO) << "Key Size: " << FLAGS_key_size << " bytes"; + LOG(INFO) << "Key Size: 128 bytes"; LOG(INFO) << "Value Size: " << FLAGS_value_size << " bytes"; LOG(INFO) << "Operations per thread: " << FLAGS_test_operation_nums; LOG(INFO) << "";