Skip to content

Performance Tests

Voice/audio file concurrent write test

The test below can be used to check the concurrent writes to a directory.
Configure the settings at the top to tune the test.

Required

This script requires fio to be installed

#!/bin/bash

# Configuration
TEST_DIR="./test"
FILE_SIZE=$((5 * 1024 * 1024))  # 5 MB file size (typical of an audio file)
BASELINE_RUNS=3       # Number of baseline runs for averaging
CONCURRENCY_LIMIT=100 # Maximum number of concurrent writes to test
PERF_DROP_THRESHOLD=40  # Stop when speed drops more than 40%
WRITE_BLOCK_SIZE=$((512 * 1024))  # 512 KB block size (common for media workloads)
START_CONCURRENCY=50  # Start concurrency at 50

# Ensure test directory exists
mkdir -p "$TEST_DIR"
rm -f "$TEST_DIR"/*  # Clear previous test files

# Check if fio is installed
FIO_AVAILABLE=0
if command -v fio &> /dev/null; then
    FIO_AVAILABLE=1
    echo "Using fio for benchmarking."
else
    echo "fio not found. Using dd instead."
fi

# Function to perform a single write
write_file() {
    local file="$TEST_DIR/audio_$1.wav"
    dd if=/dev/zero of="$file" bs=$WRITE_BLOCK_SIZE count=$(( FILE_SIZE / WRITE_BLOCK_SIZE )) oflag=dsync &>/dev/null
}

# Measure baseline performance (single writer)
echo "Measuring baseline performance..."
total_time=0
for ((i=1; i<=$BASELINE_RUNS; i++)); do
    start_time=$(date +%s.%N)
    write_file "baseline"
    end_time=$(date +%s.%N)
    elapsed_time=$(echo "$end_time - $start_time" | bc)
    total_time=$(echo "$total_time + $elapsed_time" | bc)
done
baseline_speed=$(echo "scale=2; ($FILE_SIZE * $BASELINE_RUNS) / (1024 * 1024 * $total_time)" | bc)
echo "Baseline write speed: $baseline_speed MB/s"

# Set 80% and 100% speed thresholds
MIN_ACCEPTABLE_SPEED=$(echo "scale=2; $baseline_speed * 0.8" | bc)
MAX_ACCEPTABLE_SPEED=$(echo "scale=2; $baseline_speed * 1.0" | bc)

echo "Acceptable speed range: $MIN_ACCEPTABLE_SPEED MB/s - $MAX_ACCEPTABLE_SPEED MB/s"

# Test concurrent writes
echo "Testing concurrent writes..."
best_concurrency=$START_CONCURRENCY
best_speed=$baseline_speed
max_concurrency_within_range=0

for ((concurrent_writers=$START_CONCURRENCY; concurrent_writers<=CONCURRENCY_LIMIT; concurrent_writers++)); do
    echo "Testing $concurrent_writers concurrent writes..."

    start_time=$(date +%s.%N)
    for ((i=1; i<=concurrent_writers; i++)); do
        write_file "$i" &
    done
    wait
    end_time=$(date +%s.%N)

    elapsed_time=$(echo "$end_time - $start_time" | bc)
    current_speed=$(echo "scale=2; ($FILE_SIZE * $concurrent_writers) / (1024 * 1024 * $elapsed_time)" | bc)

    echo "  Speed: $current_speed MB/s"

    # Check if speed is within the acceptable range (80-100% of baseline)
    if (( $(echo "$current_speed >= $MIN_ACCEPTABLE_SPEED && $current_speed <= $MAX_ACCEPTABLE_SPEED" | bc -l) )); then
        max_concurrency_within_range=$concurrent_writers
    fi

    # Stop if performance drops beyond threshold
    performance_drop=$(echo "scale=2; 100 - (($current_speed / $baseline_speed) * 100)" | bc)
    if (( $(echo "$performance_drop > $PERF_DROP_THRESHOLD" | bc -l) )); then
        echo "  Performance drop detected at $concurrent_writers concurrent writes!"
        break
    fi

    best_concurrency=$concurrent_writers
    best_speed=$current_speed
done

echo "---------------------------------------------------"
echo "Max concurrent writes maintaining 80-100% speed: $max_concurrency_within_range"
echo "Optimal concurrency level: $best_concurrency writers"
echo "Best achieved write speed: $best_speed MB/s"
echo "---------------------------------------------------"

# Optional: Use fio for more advanced benchmarking if available
if [ $FIO_AVAILABLE -eq 1 ]; then
    echo "Running fio test for additional benchmarking..."
    fio --name=audio_test --directory="$TEST_DIR" --size=5M --numjobs=$max_concurrency_within_range --rw=write --bs=512K --direct=1 --time_based --runtime=5 --group_reporting
fi