Skip to content

Commit

Permalink
[Perf] Develop client-server comms. program to measure L3-logging ove…
Browse files Browse the repository at this point in the history
…rheads

This commit simplifies the simple client-server communication program
to be usable as a performance test-bed to quantify the overheads of
L3-logging. Basic single/multiple-clients exchanging n-messages with server
that runs in serial manner (of processing messages) is working with this
commit.

The changes are as follows:

svmsg_file.h:
  - Define enum req_resp_type_t{} with few message types.
  - Specifically of interest are: REQ_MT_INIT, REQ_MT_INCR, REQ_MT_EXIT

svmsg_file_server.c
  - Simplified server. Receives messages inline from client in a forever
    loop. Currently, only implements "increment" counter.
  - Manages state of multiple client connections using simple array
  - L3-logging code is conditionally defined under L3_ENABLED. So,
    will need to build separately to invoke-and-test logging overheads.

svmsg_file_client.c
  - Sits in forever loop, sending "increment" message to server
  - Do this for n-iterations.

Makefile: Make changes to build the client/server programs with
 L3-logging OFF (baseline) and logging enabled.

test.sh: Add test-build-and-run-client-server-perf-test and include
  that in CI's build.yml . We will build-and-run a small scale run of
  this new test, with 5 concurrent clients, L3 ON and OFF.

build.yml: Add new test to run in CI in debug & release build modes.
  • Loading branch information
gapisback committed May 3, 2024
1 parent 94779dc commit e3884c2
Show file tree
Hide file tree
Showing 6 changed files with 384 additions and 112 deletions.
9 changes: 5 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,6 @@ jobs:
- name: test-make-help
run: ./test.sh test-make-help

#! -------------------------------------------------------------------------
- name: test-build-client-server-perf-test
run: ./test.sh test-build-client-server-perf-test

#! -------------------------------------------------------------------------
- name: test-build-and-run-unit-tests
run: BUILD_MODE=${{ matrix.build_type }} ./test.sh test-build-and-run-unit-tests
Expand Down Expand Up @@ -166,6 +162,11 @@ jobs:
# Do 'clean' here rather than 'clean-l3', so we do full rebuilds
BUILD_MODE=${{ matrix.build_type }} ./test.sh test-build-and-run-Cc-samples-with-LOC-ELF
#! -------------------------------------------------------------------------
- name: test-build-and-run-client-server-perf-test
run: |
BUILD_MODE=${{ matrix.build_type }} ./test.sh test-build-and-run-client-server-perf-test
# -------------------------------------------------------------------------
# Exercise the --from-test interface to verify that it still works to
# run thru last pair of code-formatting tests. (Minor duplication of
Expand Down
27 changes: 27 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,23 @@ LOC_TOKENS := loc_tokens.h

L3_LOC_UNSET := 0

# -----------------------------------------------------------------------------
# The driving env-var, L3_ENABLED, can be set to one of these values.
# By default, most programs are built with this ON. Only for some performance
# tests, we want to build programs with L3 OFF, then with L3 ON.
# -----------------------------------------------------------------------------
L3_DISABLED := 0
L3_DEFAULT := 1

# Set local symbol based on whether environment variable is set.
L3_ENABLED ?= $(L3_DEFAULT)

# -----------------------------------------------------------------------------
# The driving env-var, L3_LOC_ENABLED, needs to be set to one of these values.
# LOC-encoding comes in two flavours. Default technique is based on the
# Python-generator script. Enhanced technique is based on LOC-ELF
# encoding.
# -----------------------------------------------------------------------------
L3_LOC_DEFAULT := 1
L3_LOC_ELF_ENCODING := 2

Expand Down Expand Up @@ -533,6 +546,11 @@ CLIENT_SERVER_SERVER_MAIN_SRC := $(filter %_server.c, $(CLIENT_SERVER_PERF_TES
# Build list of sources other than client-/server-main sources.
CLIENT_SERVER_NON_MAIN_SRCS := $(filter-out $(CLIENT_SERVER_PERF_TESTS_DIR)/svmsg_file_%.c, $(CLIENT_SERVER_PERF_TESTS_SRCS))

# If L3-logging is enabled in test-program, need to include core library file
ifeq ($(L3_ENABLED), $(L3_DEFAULT))
CLIENT_SERVER_NON_MAIN_SRCS += $(L3_SRC)
endif

# Map the list of sources to resulting list-of-objects
CLIENT_SERVER_CLIENT_MAIN_OBJ := $(CLIENT_SERVER_CLIENT_MAIN_SRC:%.c=$(OBJDIR)/%.o)
CLIENT_SERVER_SERVER_MAIN_OBJ := $(CLIENT_SERVER_SERVER_MAIN_SRC:%.c=$(OBJDIR)/%.o)
Expand All @@ -551,6 +569,7 @@ CLIENT_SERVER_PERF_TEST_BINS := $(CLIENT_SERVER_PERF_TEST_BIN_SRCS:$(CLIENT_S
ifeq "$(BUILD_VERBOSE)" "1"
$(info )
$(info ---- Debug ----)
$(info $$L3_ENABLED = [ ${L3_ENABLED} ])
$(info $$CLIENT_SERVER_PERF_TESTS_DIR = [ ${CLIENT_SERVER_PERF_TESTS_DIR} ])
$(info $$CLIENT_SERVER_PERF_TESTS_SRCS = [ ${CLIENT_SERVER_PERF_TESTS_SRCS} ])
$(info $$CLIENT_SERVER_PERF_TEST_BIN_SRCS = [ ${CLIENT_SERVER_PERF_TEST_BIN_SRCS} ])
Expand Down Expand Up @@ -583,6 +602,14 @@ ifeq "$(BUILD_MODE)" "debug"
CFLAGS += -DDEBUG
endif

# By default, L3-logging is always ON for all programs built here.
# So, the -DL3_ENABLED flag is really just a documentation pass-through.
# Except, some performance benchmarking programs are built with L3 OFF to
# compare the performance of the benchmark with L3 ON.
ifeq ($(L3_ENABLED), $(L3_DEFAULT))
CFLAGS += -DL3_ENABLED
endif

# By default, L3-logging runs on its own. To integrate L3 with LOC machinery,
# to squirrel away the loc_t ID value, run: L3_LOC_ENABLED=1 make ...
ifeq ($(L3_LOC_ENABLED), $(L3_LOC_DEFAULT))
Expand Down
55 changes: 52 additions & 3 deletions test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ TestList=(
"test-build-and-run-C-samples-with-LOC-ELF"
"test-build-and-run-Cpp-samples-with-LOC-ELF"
"test-build-and-run-Cc-samples-with-LOC-ELF"
"test-build-client-server-perf-test"
"test-build-and-run-client-server-perf-test"

"test-pytests"

Expand Down Expand Up @@ -281,10 +281,59 @@ function test-build-and-run-Cc-samples-with-LOC-ELF()
}

# #############################################################################
function test-build-client-server-perf-test()
function test-build-and-run-client-server-perf-test()
{
set +x

echo " "
echo "${Me}: Client-server performance testing with L3-logging OFF:"
echo " "
build-and-run-client-server-perf-test 0

echo " "
echo "${Me}: Client-server performance testing with L3-logging ON:"
echo " "
build-and-run-client-server-perf-test 1

echo " "
echo "${Me}: Completed basic client(s)-server communication test."
echo " "
}

# #############################################################################
# Minion to test-build-and-run-client-server-perf-test(), to actually perform
# the build and run the client/server application for performance benchmarking.
# #############################################################################
function build-and-run-client-server-perf-test()
{
l3_enabled=$1

set +x
# Makefile does not implement 'run' step. Do it here manually.
local server_bin="./build/${Build_mode}/bin/use-cases/svmsg_file_server"
local client_bin="./build/${Build_mode}/bin/use-cases/svmsg_file_client"

set -x
make clean
make clean && CXX=g++ LD=g++ make client-server-perf-test
make clean && CXX=g++ LD=g++ L3_ENABLED=${l3_enabled} make client-server-perf-test

${server_bin} &

set +x
sleep 5

local numclients=5
local ictr=0
while [ ${ictr} -lt ${numclients} ]; do

set -x
${client_bin} 1000 &
set +x

ictr=$((ictr + 1))
done

wait
}

# #############################################################################
Expand Down
65 changes: 44 additions & 21 deletions use-cases/client-server-msgs-perf/svmsg_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,52 @@

#define SERVER_KEY 0x1aaaaaa1 /* Key for server's message queue */

struct requestMsg { /* Requests (client to server) */
long mtype; /* Unused */
int clientId; /* ID of client's message queue */
char pathname[PATH_MAX]; /* File to be returned */
};

/* REQ_MSG_SIZE computes size of 'mtext' part of 'requestMsg' structure.
We use offsetof() to handle the possibility that there are padding
bytes between the 'clientId' and 'pathname' fields.
*/
#define MAX_CLIENTS 64

/**
* Types for request / response messages sent from server to client
*/
typedef enum {
REQ_MT_UNKNOWN = 0
, REQ_MT_INIT = 1 // New client initialization
, REQ_MT_INCR // Increment client's counter
, REQ_MT_DECR // Decrement client's counter
, REQ_MT_GET_CTR // Retrieve current state of counter
, REQ_MT_QUIT // This client wants to quit

// Server will send RESP_MT_QUIT to all active clients.
, REQ_MT_EXIT // Client asks application to exit

// Response message types send by server to client.
, RESP_MT_FAILURE // Some failure indicator recd from server
, RESP_MT_DATA // Message contains data (counter)
, RESP_MT_END // End of message stream (unused)
, RESP_MT_INCR = REQ_MT_INCR
, RESP_MT_DECR = REQ_MT_DECR
, RESP_MT_QUIT = REQ_MT_QUIT


} req_resp_type_t;


typedef struct requestMsg { /* Requests (client to server) */
req_resp_type_t mtype; /* Request msg type */
int clientId; /* ID of client's message queue */
int client_idx; /* Client's index on server-side array */
int64_t counter; /* Client's counter value */
} requestMsg;

#define REQ_MSG_SIZE (offsetof(struct requestMsg, pathname) - \
offsetof(struct requestMsg, clientId) + PATH_MAX)
#define REQ_MSG_SIZE sizeof(requestMsg)

#define RESP_MSG_SIZE 8192
// At client initialization time, we don't know its index on server-side
#define REQ_CLIENT_INDEX_UNKNOWN ((int) -1)

struct responseMsg { /* Responses (server to client) */
long mtype; /* One of RESP_MT_* values below */
char data[RESP_MSG_SIZE]; /* File content / response message */
};
typedef struct responseMsg { /* Responses (server to client) */
req_resp_type_t mtype; /* One of request/response type IDs */
int clientId; /* ID of client's message queue */
int client_idx; /* Client's index on server-side array */
int64_t counter; /* Client's counter value */
} responseMsg;

/* Types for response messages sent from server to client */
#define RESP_MSG_SIZE sizeof(responseMsg)

#define RESP_MT_FAILURE 1 /* File couldn't be opened */
#define RESP_MT_DATA 2 /* Message contains file data */
#define RESP_MT_END 3 /* File data complete */
Loading

0 comments on commit e3884c2

Please sign in to comment.