aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetri Savolainen <petri.savolainen@nokia.com>2024-03-08 12:40:14 +0200
committerMatias Elo <matias.elo@nokia.com>2024-04-26 17:19:19 +0300
commit7fdabeb322fb0f05eefc0a2299d45c8d45c267f9 (patch)
tree17129a7c3a36adf7ffc4f6f1c156d7b7202b9c08
parentbc854b8eab342247da1f927a870f68a3774a10d5 (diff)
helper: stress: add new CPU stress functions
CPU stress functions may be used in test applications to create dummy CPU load. Functions are not highly optimized but try to stress various parts of CPU instruction set. Signed-off-by: Petri Savolainen <petri.savolainen@nokia.com> Reviewed-by: Matias Elo <matias.elo@nokia.com>
-rw-r--r--helper/Makefile.am1
-rw-r--r--helper/include/odp/helper/odph_api.h1
-rw-r--r--helper/include/odp/helper/stress.h238
-rw-r--r--helper/test/.gitignore1
-rw-r--r--helper/test/Makefile.am2
-rw-r--r--helper/test/stress.c118
6 files changed, 361 insertions, 0 deletions
diff --git a/helper/Makefile.am b/helper/Makefile.am
index bca50873e..fd6a9f34a 100644
--- a/helper/Makefile.am
+++ b/helper/Makefile.am
@@ -30,6 +30,7 @@ helperinclude_HEADERS = \
include/odp/helper/odph_iplookuptable.h\
include/odp/helper/odph_lineartable.h\
include/odp/helper/sctp.h \
+ include/odp/helper/stress.h\
include/odp/helper/string.h\
include/odp/helper/strong_types.h\
include/odp/helper/tcp.h\
diff --git a/helper/include/odp/helper/odph_api.h b/helper/include/odp/helper/odph_api.h
index d2ac2a55a..e3833d2dd 100644
--- a/helper/include/odp/helper/odph_api.h
+++ b/helper/include/odp/helper/odph_api.h
@@ -29,6 +29,7 @@ extern "C" {
#include <odp/helper/ip.h>
#include <odp/helper/ipsec.h>
#include <odp/helper/macros.h>
+#include <odp/helper/stress.h>
#include <odp/helper/odph_lineartable.h>
#include <odp/helper/odph_iplookuptable.h>
#include <odp/helper/sctp.h>
diff --git a/helper/include/odp/helper/stress.h b/helper/include/odp/helper/stress.h
new file mode 100644
index 000000000..cfdc41033
--- /dev/null
+++ b/helper/include/odp/helper/stress.h
@@ -0,0 +1,238 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2024 Nokia
+ */
+
+/**
+ * @file
+ *
+ * ODP helper stress
+ */
+
+#ifndef ODPH_STRESS_H_
+#define ODPH_STRESS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup odph_stress ODPH STRESS
+ * Dummy CPU stress functions
+ *
+ * These functions may be used in test applications to create dummy CPU load. Functions are not
+ * highly optimized, as they try to utilize various parts of CPU instruction set (load/store,
+ * branch, integer/float arithmetics, vector, etc. instructions).
+ *
+ * @{
+ */
+
+/**
+ * Returns 'value' raised to the power of 2
+ *
+ * @param value Base value
+ *
+ * @return The value raised to the power of 2
+ */
+static inline uint32_t odph_stress_pow2_u32(uint32_t value)
+{
+ uint64_t v = (uint64_t)value;
+ uint64_t res = v * v;
+
+ if (odp_unlikely(res > UINT32_MAX))
+ return UINT32_MAX;
+
+ return (uint32_t)res;
+}
+
+/**
+ * Returns base 2 logarithm of 'value'
+ *
+ * @param value The value for which the logarithm is being calculated
+ *
+ * @return Base 2 logarithm of 'value'
+ */
+static inline uint32_t odph_stress_log2_u32(uint32_t value)
+{
+ uint32_t ret = 0;
+
+ while ((value >>= 1) != 0)
+ ret++;
+
+ return ret;
+}
+
+/**
+ * Calculates square root of a 32-bit unsigned integer value
+ *
+ * @param value The value for which the square root is being calculated
+ *
+ * @return Square root of the value
+ */
+static inline uint32_t odph_stress_sqrt_u32(uint32_t value)
+{
+ uint64_t x;
+ uint64_t pow = 1;
+
+ if (odp_unlikely(value == 0 || value == 1))
+ return value;
+
+ if (value & 0xffff0000) {
+ if (value & 0xff000000) {
+ if (value & 0xf0000000) {
+ x = 16384;
+ if (value & 0xe0000000)
+ x = 23170;
+ if (value & 0xc0000000)
+ x = 32768;
+ if (value & 0x80000000)
+ x = 46340;
+ } else {
+ /* value & 0x0f000000 */
+ x = 4096;
+ if (value & 0x0e000000)
+ x = 5792;
+ if (value & 0x0c000000)
+ x = 8192;
+ if (value & 0x08000000)
+ x = 11585;
+ }
+ } else {
+ if (value & 0x00f00000) {
+ x = 1024;
+ if (value & 0x00e00000)
+ x = 1448;
+ if (value & 0x00c00000)
+ x = 2048;
+ if (value & 0x00800000)
+ x = 2896;
+ } else {
+ /* value & 0x000f0000 */
+ x = 256;
+ if (value & 0x000e0000)
+ x = 362;
+ if (value & 0x000c0000)
+ x = 512;
+ if (value & 0x00080000)
+ x = 724;
+ }
+ }
+ } else {
+ /* value & 0xffff */
+ x = 1;
+
+ if (value >= 16384) {
+ x = 128;
+ if (value >= 25600)
+ x = 160;
+ if (value >= 36864)
+ x = 192;
+ if (value >= 50176)
+ x = 224;
+ } else {
+ if (value >= 1024)
+ x = 32;
+ if (value >= 4096)
+ x = 64;
+ if (value >= 9216)
+ x = 96;
+ }
+ }
+
+ while (pow <= value) {
+ x++;
+ pow = x * x;
+ }
+
+ return (uint32_t)(x - 1);
+}
+
+/**
+ * Calculates square root of a floating point value
+ *
+ * @param value The value for which the square root is being calculated
+ *
+ * @return Square root of the value
+ */
+static inline float odph_stress_sqrt_f32(float value)
+{
+ double x;
+ double pow = 1;
+
+ if (odp_unlikely(value == 0 || value == 1))
+ return value;
+
+ if (value >= 65536) {
+ if (value >= 16777215) {
+ if (value >= 268435456) {
+ x = 16384;
+ if (value >= 536870912)
+ x = 23170;
+ if (value >= 1073741824)
+ x = 32768;
+ if (value >= 2147483648)
+ x = 46340;
+ } else {
+ x = 4096;
+ if (value >= 33554432)
+ x = 5792;
+ if (value >= 67108864)
+ x = 8192;
+ if (value >= 134217728)
+ x = 11585;
+ }
+ } else {
+ if (value >= 1048576) {
+ x = 1024;
+ if (value >= 2097152)
+ x = 1448;
+ if (value >= 4194304)
+ x = 2048;
+ if (value >= 8388608)
+ x = 2896;
+ } else {
+ x = 256;
+ if (value >= 131072)
+ x = 362;
+ if (value >= 262144)
+ x = 512;
+ if (value >= 524288)
+ x = 724;
+ }
+ }
+ } else {
+ x = 1;
+
+ if (value >= 16384) {
+ x = 128;
+ if (value >= 25600)
+ x = 160;
+ if (value >= 36864)
+ x = 192;
+ if (value >= 50176)
+ x = 224;
+ } else {
+ if (value >= 1024)
+ x = 32;
+ if (value >= 4096)
+ x = 64;
+ if (value >= 9216)
+ x = 96;
+ }
+ }
+
+ while (pow <= value) {
+ x = x + 1;
+ pow = x * x;
+ }
+
+ return (float)(x - 1);
+}
+
+/**
+ * @}
+ */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/helper/test/.gitignore b/helper/test/.gitignore
index 3db451f68..7fe2d0ce9 100644
--- a/helper/test/.gitignore
+++ b/helper/test/.gitignore
@@ -8,6 +8,7 @@ macros
odpthreads
parse
process
+stress
table
thread
pthread
diff --git a/helper/test/Makefile.am b/helper/test/Makefile.am
index 9cf48d7d9..976b8cf65 100644
--- a/helper/test/Makefile.am
+++ b/helper/test/Makefile.am
@@ -6,6 +6,7 @@ EXECUTABLES = version \
cuckootable \
macros \
parse\
+ stress \
table \
iplookuptable
@@ -43,6 +44,7 @@ cuckootable_SOURCES = cuckootable.c
macros_SOURCES = macros.c
odpthreads_SOURCES = odpthreads.c
parse_SOURCES = parse.c
+stress_SOURCES = stress.c
table_SOURCES = table.c
iplookuptable_SOURCES = iplookuptable.c
version_SOURCES = version.c
diff --git a/helper/test/stress.c b/helper/test/stress.c
new file mode 100644
index 000000000..e66a0447d
--- /dev/null
+++ b/helper/test/stress.c
@@ -0,0 +1,118 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2024 Nokia
+ */
+
+#include <odp_api.h>
+#include <odp/helper/odph_api.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static int test_pow2(void)
+{
+ uint32_t in[] = {0, 1, 2, 3, 4, 0xff, 0x100, 0xfffe, 0xffff, 0x10000};
+ uint32_t out[] = {0, 1, 4, 9, 16, 0xfe01, 0x10000, 0xfffc0004, 0xfffe0001, 0xffffffff};
+ uint32_t num = ODPH_ARRAY_SIZE(out);
+ int ret = 0;
+
+ printf(" odph_stress_pow2_u32() ... ");
+
+ for (uint32_t i = 0; i < num; i++)
+ if (odph_stress_pow2_u32(in[i]) != out[i])
+ ret++;
+
+ if (ret)
+ printf("%i tests failed\n", ret);
+ else
+ printf("passed\n");
+
+ return ret;
+}
+
+static int test_log2(void)
+{
+ uint32_t in[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 15, 16, 255, 256, 257, 512, 513, 1023, 1024};
+ uint32_t out[] = {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 4, 7, 8, 8, 9, 9, 9, 10};
+ uint32_t num = ODPH_ARRAY_SIZE(out);
+ int ret = 0;
+
+ printf(" odph_stress_log2_u32() ... ");
+
+ for (uint32_t i = 0; i < num; i++)
+ if (odph_stress_log2_u32(in[i]) != out[i])
+ ret++;
+
+ if (ret)
+ printf("%i tests failed\n", ret);
+ else
+ printf("passed\n");
+
+ return ret;
+}
+
+static int test_sqrt_u32(void)
+{
+ uint32_t in[] = {0, 1, 2, 3, 4, 7, 8, 9, 100, 1500, 2900, 4096, 6213, 8191, 16384, 100000,
+ 1000000, 4036587, 0x42c1d80, 0x8000000, 0x1fffffff, 0x2faf0800,
+ 0xffffffff};
+ uint32_t out[] = {0, 1, 1, 1, 2, 2, 2, 3, 10, 38, 53, 64, 78, 90, 128, 316, 1000, 2009,
+ 8366, 11585, 23170, 28284, 65535};
+ uint32_t num = ODPH_ARRAY_SIZE(out);
+ int ret = 0;
+
+ printf(" odph_stress_sqrt_u32() ... ");
+
+ for (uint32_t i = 0; i < num; i++)
+ if (odph_stress_sqrt_u32(in[i]) != out[i])
+ ret++;
+
+ if (ret)
+ printf("%i tests failed\n", ret);
+ else
+ printf("passed\n");
+
+ return ret;
+}
+
+/*
+ * 32-bit floating point can represent integers between 0 and 16777216 exactly, and integers
+ * between 16777216 and 33554432 in multiples of 2, etc.
+ */
+static int test_sqrt_f32(void)
+{
+ float in[] = {0, 1, 2, 3, 4, 7, 8, 9, 100, 1500, 2900, 4096, 6213, 8191, 16384, 100000,
+ 1000000, 4036587, 16777216, 33554432, 134217728, 3000000000, 4294967296};
+ float out[] = {0, 1, 1, 1, 2, 2, 2, 3, 10, 38, 53, 64, 78, 90, 128, 316, 1000, 2009, 4096,
+ 5792, 11585, 54772, 65536};
+ uint32_t num = ODPH_ARRAY_SIZE(out);
+ int ret = 0;
+
+ printf(" odph_stress_sqrt_f32() ... ");
+
+ for (uint32_t i = 0; i < num; i++)
+ if (odph_stress_sqrt_f32(in[i]) != out[i])
+ ret++;
+
+ if (ret)
+ printf("%i tests failed\n", ret);
+ else
+ printf("passed\n");
+
+ return ret;
+}
+
+int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED)
+{
+ int ret = 0;
+
+ printf("Running helper algorithm tests:\n");
+
+ ret += test_pow2();
+ ret += test_log2();
+ ret += test_sqrt_u32();
+ ret += test_sqrt_f32();
+
+ printf("\n");
+
+ return ret ? EXIT_FAILURE : EXIT_SUCCESS;
+}