Add repeatable NAT benchmarks for table size, payload size and full-pool misses
This commit is contained in:
1 parent
55cc721c9b
commit
2c10272e15
1 file changed
+68
-1
+68
-1
@@ -10,6 +10,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "../lib/platform_compat.h"
|
||||
#include "../lib/u_async.h"
|
||||
#include "../lib/mem.h"
|
||||
#include "../lib/debug_config.h"
|
||||
#include "../src/eim_nat.h"
|
||||
#include "etcp.h"
|
||||
@@ -475,10 +477,75 @@ static void stress_large_table_init_free(void) {
|
||||
PASS();
|
||||
}
|
||||
|
||||
/* Восстановить только изменяемые NAT поля: длина payload не попадает в стоимость поиска/пересчёта заголовков. */
|
||||
static void benchmark_reset(uint8_t* packet, const uint8_t* original) {
|
||||
memcpy(packet + 10, original + 10, 2);
|
||||
memcpy(packet + 12, original + 12, 4);
|
||||
memcpy(packet + 20, original + 20, 2);
|
||||
}
|
||||
|
||||
/* Воспроизводимый microbenchmark: подготовка и аллокации вне измерений, одинаковый build и отключённая диагностика. */
|
||||
static int benchmark_nat(void) {
|
||||
debug_set_category_level(DEBUG_CATEGORY_NAT, DEBUG_LEVEL_DISABLED);
|
||||
const uint32_t populations[] = {1, 1000, 10000, 60000};
|
||||
const size_t lengths[] = {64, 1500};
|
||||
for (size_t length_index = 0; length_index < 2; length_index++) {
|
||||
size_t len = lengths[length_index];
|
||||
uint8_t original[1500] = {0}, packet[1500];
|
||||
size_t built;
|
||||
uint8_t* seed = make_udp_pkt(0x0a000002, 40000, 0x08080808, 53, &built);
|
||||
if (!seed) return 1;
|
||||
memcpy(original, seed, built); free(seed);
|
||||
uint16_t word = htobe16(len); memcpy(original + 2, &word, 2);
|
||||
word = htobe16(len - 20); memcpy(original + 24, &word, 2);
|
||||
memset(original + 10, 0, 2);
|
||||
uint32_t sum = 0;
|
||||
for (size_t j = 0; j < 20; j += 2) { memcpy(&word, original + j, 2); sum += word; }
|
||||
sum = (sum & 0xffff) + (sum >> 16); sum = (sum & 0xffff) + (sum >> 16);
|
||||
word = (uint16_t)~sum; memcpy(original + 10, &word, 2);
|
||||
for (size_t population_index = 0; population_index < 4; population_index++) {
|
||||
uint32_t count = populations[population_index];
|
||||
struct global_config g = make_config(1, count > 1 ? count : 2);
|
||||
struct eim_nat_ctx ctx;
|
||||
if (eim_nat_init_ctx(&ctx, &g)) return 1;
|
||||
memcpy(packet, original, len);
|
||||
size_t allocations = u_get_allocated_count();
|
||||
uint64_t start = get_time_us();
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
benchmark_reset(packet, original);
|
||||
if (eim_nat_egress(&ctx, packet, len, i + 1, NULL)) { eim_nat_destroy_ctx(&ctx); return 1; }
|
||||
}
|
||||
uint64_t creation = get_time_us() - start;
|
||||
start = get_time_us();
|
||||
const uint32_t iterations = 200000;
|
||||
for (uint32_t i = 0; i < iterations; i++) {
|
||||
benchmark_reset(packet, original);
|
||||
if (eim_nat_egress(&ctx, packet, len, (i * 2654435761u) % count + 1, NULL)) { eim_nat_destroy_ctx(&ctx); return 1; }
|
||||
}
|
||||
uint64_t hits = get_time_us() - start;
|
||||
if (count == 1) { benchmark_reset(packet, original); eim_nat_egress(&ctx, packet, len, 2, NULL); }
|
||||
start = get_time_us();
|
||||
for (uint32_t i = 0; i < iterations; i++) {
|
||||
benchmark_reset(packet, original);
|
||||
if (eim_nat_egress(&ctx, packet, len, UINT64_MAX, NULL) != EIM_NAT_ERROR) { eim_nat_destroy_ctx(&ctx); return 1; }
|
||||
}
|
||||
uint64_t misses = get_time_us() - start;
|
||||
int balanced = u_get_allocated_count() == allocations;
|
||||
printf("BENCH bytes=%zu flows=%u create_ns=%.1f hit_ns=%.1f full_miss_ns=%.1f heap_growth=%d\n", len, count,
|
||||
creation * 1000.0 / count, hits * 1000.0 / iterations, misses * 1000.0 / iterations, !balanced);
|
||||
eim_nat_destroy_ctx(&ctx);
|
||||
if (!balanced) return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ==================== Main ====================
|
||||
int main(void) {
|
||||
int main(int argc, char** argv) {
|
||||
debug_config_init();
|
||||
debug_set_level(DEBUG_LEVEL_ERROR);
|
||||
if (argc == 2 && !strcmp(argv[1], "--benchmark")) return benchmark_nat();
|
||||
if (argc != 1) { DEBUG_ERROR(DEBUG_CATEGORY_NAT, "Usage: test_nat_stress [--benchmark]"); return 1; }
|
||||
|
||||
stress_many_sessions();
|
||||
stress_table_full_and_lookup();
|
||||
|
||||
Reference in new issue
Block a user