-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Rule Timothy (VM/EMT3) <Timothy.Rule@de.bosch.com>
- Loading branch information
1 parent
9472f17
commit cff79ae
Showing
5 changed files
with
365 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
|
||
version: '3' | ||
|
||
vars: | ||
GO_BUILDER_IMAGE: golang:bullseye | ||
GCC_BUILDER_IMAGE: golang:bullseye | ||
|
||
tasks: | ||
|
||
benchmark-tools: | ||
run: when_changed | ||
dir: '{{.USER_WORKING_DIR}}' | ||
cmds: | ||
- mkdir -p build | ||
- docker run --rm -v $(pwd):/tmp -w /tmp {{.GO_BUILDER_IMAGE}} go build -o build/benchmark-gen benchmark-gen.go | ||
sources: | ||
- benchmark-gen.go | ||
generates: | ||
- build/benchmark-gen | ||
|
||
benchmark-gen: | ||
run: always | ||
deps: | ||
- benchmark-tools | ||
dir: '{{.USER_WORKING_DIR}}' | ||
vars: | ||
SIGNALCOUNT: '{{.SIGNALCOUNT | default 2}}' | ||
cmds: | ||
- mkdir -p build | ||
- build/benchmark-gen --signals {{.SIGNALCOUNT}} | ||
sources: | ||
- build/benchmark-gen | ||
- template/network_ct_front.tmpl | ||
- template/network_ct_body.tmpl | ||
generates: | ||
- build/network_ct.c | ||
|
||
benchmark-build: | ||
run: always | ||
dir: '{{.USER_WORKING_DIR}}' | ||
vars: | ||
SIGNALCOUNT: '{{.SIGNALCOUNT | default 2}}' | ||
cmds: | ||
- docker run --rm -v $(pwd):/tmp -w /tmp {{.GCC_BUILDER_IMAGE}} | ||
gcc -shared -o build/network_ct.so -Wall -fpic build/network_ct.c | ||
- docker run --rm -v $(pwd):/tmp -w /tmp {{.GCC_BUILDER_IMAGE}} | ||
gcc -o build/bench_net -Wall bench_net.c -ldl | ||
sources: | ||
- build/network_ct.c | ||
- bench_net.c | ||
generates: | ||
- build/network_ct.so | ||
- build/bench_net | ||
|
||
benchmark: | ||
run: always | ||
dir: '{{.USER_WORKING_DIR}}' | ||
vars: | ||
SIGNALCOUNT: '{{.SIGNALCOUNT | default 1000}}' | ||
cmds: | ||
- task: benchmark-gen | ||
vars: { SIGNALCOUNT: '{{.SIGNALCOUNT}}' } | ||
- task: benchmark-build | ||
- ls -R build/ | ||
- build/bench_net {{.SIGNALCOUNT}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
|
||
#include <stdio.h> | ||
#include <stdint.h> | ||
#include <stdbool.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <dlfcn.h> | ||
#include <time.h> | ||
#include <unistd.h> | ||
|
||
|
||
struct timespec get_timespec_now(void) | ||
{ | ||
struct timespec ts = {}; | ||
clock_gettime(CLOCK_MONOTONIC, &ts); | ||
return ts; | ||
} | ||
|
||
|
||
uint64_t get_elapsedtime_ns(struct timespec ref) | ||
{ | ||
struct timespec now = get_timespec_now(); | ||
if (ref.tv_sec == now.tv_sec) { | ||
return now.tv_nsec - ref.tv_nsec; | ||
} else { | ||
return ((now.tv_sec - ref.tv_sec) * 1000000000) + | ||
(now.tv_nsec - ref.tv_nsec); | ||
} | ||
} | ||
|
||
double ns_to_us_to_sec(uint64_t t_ns) | ||
{ | ||
uint32_t t_us = t_ns / 1000; | ||
return t_us / 1000000.0; | ||
} | ||
|
||
typedef int (*PackFunc)(uint8_t*, const void*, size_t); | ||
typedef int (*UnpackFunc)(void*, const uint8_t*, size_t); | ||
typedef bool (*RangeFunc)(uint8_t value); | ||
typedef double (*DecodeFunc)(uint8_t value); | ||
typedef uint8_t (*EncodeFunc)(double signal); | ||
|
||
|
||
typedef struct signal_t { | ||
int count; | ||
PackFunc pack_func; | ||
UnpackFunc unpack_func; | ||
RangeFunc range_func; | ||
DecodeFunc decode_func; | ||
EncodeFunc encode_func; | ||
|
||
uint8_t buffer[8]; | ||
uint8_t pack[16]; | ||
} signal_t; | ||
|
||
|
||
void* _get_func_handle(void* handle, const char* fmt, int index) | ||
{ | ||
char b[1000]; | ||
snprintf(b, 1000, fmt, index); | ||
// printf(" loading function : %s\n", b); | ||
void* func = dlsym(handle, b); | ||
if (func == NULL) { | ||
printf("Could not load function from library! (%s)", dlerror()); | ||
exit(1); | ||
} | ||
return func; | ||
} | ||
|
||
|
||
void run_bench_ct(double* signals, signal_t* st, int count, int steps) | ||
{ | ||
struct timespec _ts = get_timespec_now(); | ||
|
||
for (int step = 0; step < steps; step++) { | ||
for (int i = 0; i < count; i++) { | ||
// Encode | ||
double original = signals[i]; | ||
double value = original + 1; | ||
// printf(" signal[%d] val=%f (orig=%f) .. ", i, value, original); | ||
if (value > 100) value = 0.0; | ||
st[i].buffer[0] = st[i].encode_func(value); | ||
st[i].pack_func(st[i].pack, st[i].buffer, 8); | ||
// Decode | ||
st[i].buffer[0] = 0; | ||
st[i].unpack_func(st[i].buffer, st[i].pack, 8); | ||
if (st[i].range_func(st[i].buffer[0])) { | ||
value = st[i].decode_func(st[i].buffer[0]); | ||
} else { | ||
value = value + 1; | ||
// printf(" .. out of range .. "); | ||
} | ||
// printf("val=%f (orig=%f)\n", value, original); | ||
signals[i] = value; | ||
} | ||
} | ||
|
||
uint64_t time_ns = get_elapsedtime_ns(_ts); | ||
printf("CANtools: Time %.9f (steps=%d, signals=%d)\n", | ||
ns_to_us_to_sec(time_ns), steps, count); | ||
} | ||
|
||
|
||
void run_bench_loop(double* signals, signal_t* st, int count, int steps) | ||
{ | ||
struct timespec _ts = get_timespec_now(); | ||
|
||
for (int step = 0; step < steps; step++) { | ||
for (int i = 0; i < count; i++) { | ||
// Encode | ||
double original = signals[i]; | ||
double value = original + 1; | ||
if (value > 100) value = 0.0; | ||
st[i].buffer[0] = (uint8_t)(value / 0.5); | ||
// memset(st[i].pack, 0, 8); | ||
st[i].pack[0] |= | ||
(uint8_t)((uint8_t)(st[i].buffer[0] << 1u) & 0x7eu); | ||
// Decode | ||
st[i].buffer[0] = (uint8_t)((uint8_t)(st[i].pack[0] & 0x7eu) >> 1u); | ||
; | ||
if (st[i].buffer[0] <= 200u) { | ||
value = (double)st[i].buffer[0] * 0.5; | ||
} else { | ||
value = value + 1; | ||
// printf(" .. out of range .. "); | ||
} | ||
// printf("val=%f (orig=%f)\n", value, original); | ||
signals[i] = value; | ||
} | ||
} | ||
|
||
uint64_t time_ns = get_elapsedtime_ns(_ts); | ||
printf("LOOP: Time %.9f (steps=%d, signals=%d)\n", | ||
ns_to_us_to_sec(time_ns), steps, count); | ||
} | ||
|
||
|
||
int main(int argc, char** argv) | ||
{ | ||
if (argc != 2) { | ||
printf("Incorrect arguments!"); | ||
exit(1); | ||
} | ||
int signalCount = argv[1] ? atoi(argv[1]) : 0; | ||
int steps = 10; | ||
|
||
printf("Running Network CANtools benchmark\n"); | ||
printf("signals : %d\n", signalCount); | ||
|
||
void* handle = dlopen("build/network_ct.so", RTLD_NOW | RTLD_GLOBAL); | ||
if (handle == NULL) { | ||
printf("Could not open message library! (%s)", dlerror()); | ||
exit(1); | ||
} | ||
|
||
printf(" loading signal functions ...\n"); | ||
signal_t* signal_table = calloc(signalCount, sizeof(signal_t)); | ||
for (int i = 0; i < signalCount; i++) { | ||
signal_table[i].pack_func = | ||
_get_func_handle(handle, "message%d_pack", i); | ||
signal_table[i].unpack_func = | ||
_get_func_handle(handle, "message%d_unpack", i); | ||
signal_table[i].range_func = | ||
_get_func_handle(handle, "message%d_signal_is_in_range", i); | ||
signal_table[i].decode_func = | ||
_get_func_handle(handle, "message%d_signal_decode", i); | ||
signal_table[i].encode_func = | ||
_get_func_handle(handle, "message%d_signal_encode", i); | ||
} | ||
|
||
double* signals = calloc(signalCount, sizeof(double)); | ||
for (int i = 0; i < signalCount; i++) { | ||
signals[i] = i % 100; | ||
} | ||
printf(" run cantools based benchmark ...\n"); | ||
run_bench_ct(signals, signal_table, signalCount, steps); | ||
run_bench_loop(signals, signal_table, signalCount, steps); | ||
|
||
|
||
exit(0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package main | ||
|
||
import ( | ||
"flag" | ||
"fmt" | ||
"os" | ||
"text/template" | ||
) | ||
|
||
func main() { | ||
var signalCount = flag.Int("signals", 1, "benchmark N signals") | ||
var netCt = flag.String("net_ct", "network_ct", "generated network (on basis cantools)") | ||
flag.Parse() | ||
|
||
fmt.Printf("Generate benchmark code for %d signals ...\n", *signalCount) | ||
file, _ := os.Create(fmt.Sprintf("build/%s.c", *netCt)) | ||
defer file.Close() | ||
|
||
// Front matter | ||
tmpl := template.Must(template.ParseFiles(fmt.Sprintf("template/%s_front.tmpl", *netCt))) | ||
tmpl.Execute(file, nil) | ||
|
||
// Body content | ||
tmpl = template.Must(template.ParseFiles(fmt.Sprintf("template/%s_body.tmpl", *netCt))) | ||
for i := 0; i < *signalCount; i++ { | ||
tmpl.Execute(file, i) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
|
||
int message{{.}}_pack( | ||
uint8_t *dst_p, | ||
const struct message_t *src_p, | ||
size_t size) | ||
{ | ||
if (size < 8u) { | ||
return (-EINVAL); | ||
} | ||
|
||
memset(&dst_p[0], 0, 8); | ||
|
||
dst_p[0] |= pack_left_shift_u8(src_p->radius, 1u, 0x7eu); | ||
|
||
return (8); | ||
} | ||
|
||
int message{{.}}_unpack( | ||
struct message_t *dst_p, | ||
const uint8_t *src_p, | ||
size_t size) | ||
{ | ||
if (size < 8u) { | ||
return (-EINVAL); | ||
} | ||
|
||
dst_p->radius = unpack_right_shift_u8(src_p[0], 1u, 0x7eu); | ||
|
||
return (0); | ||
} | ||
|
||
int message{{.}}_init(struct message_t *msg_p) | ||
{ | ||
if (msg_p == NULL) return -1; | ||
|
||
memset(msg_p, 0, sizeof(struct message_t)); | ||
|
||
return 0; | ||
} | ||
|
||
uint8_t message{{.}}_signal_encode(double value) | ||
{ | ||
return (uint8_t)(value / 0.1); | ||
} | ||
|
||
double message{{.}}_signal_decode(uint8_t value) | ||
{ | ||
return ((double)value * 0.1); | ||
} | ||
|
||
bool message{{.}}_signal_is_in_range(uint8_t value) | ||
{ | ||
return (value <= 50u); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
|
||
#include <stdint.h> | ||
#include <stdbool.h> | ||
#include <stddef.h> | ||
#include <string.h> | ||
|
||
#ifndef EINVAL | ||
# define EINVAL 22 | ||
#endif | ||
|
||
|
||
|
||
struct message_t { | ||
/** | ||
* Range: 0..50 (0..5 m) | ||
* Scale: 0.1 | ||
* Offset: 0 | ||
*/ | ||
uint8_t radius; | ||
}; | ||
|
||
static inline uint8_t pack_left_shift_u8( | ||
uint8_t value, | ||
uint8_t shift, | ||
uint8_t mask) | ||
{ | ||
return (uint8_t)((uint8_t)(value << shift) & mask); | ||
} | ||
|
||
static inline uint8_t unpack_right_shift_u8( | ||
uint8_t value, | ||
uint8_t shift, | ||
uint8_t mask) | ||
{ | ||
return (uint8_t)((uint8_t)(value & mask) >> shift); | ||
} | ||
|