qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 7/9] tests/performance: Add nightly tests


From: Aleksandar Markovic
Subject: Re: [PATCH 7/9] tests/performance: Add nightly tests
Date: Wed, 2 Sep 2020 10:36:47 +0200



On Friday, August 28, 2020, Ahmed Karaman <ahmedkhaledkaraman@gmail.com> wrote:
A nightly performance testing system to monitor any change in QEMU
performance across seventeen different targets.


Reviewed-by: Aleksandar Markovic <aleksandar.qemu.devel@gmail.com>

 
The system includes eight different benchmarks to provide a variety
of testing workloads.

dijkstra_double:
Find the shortest path between the source node and all other nodes
using Dijkstra’s algorithm. The graph contains n nodes where all nxn
distances are double values. The value of n can be specified using
the -n flag. The default value is 2000.

dijkstra_int32:
Find the shortest path between the source node and all other nodes
using Dijkstra’s algorithm. The graph contains n nodes where all nxn
distances are int32 values. The value of n can be specified using
the -n flag. The default value is 2000.

matmult_double:
Standard matrix multiplication of an n*n matrix of randomly generated
double numbers from 0 to 100. The value of n is passed as an argument
with the -n flag. The default value is 200.

matmult_int32:
Standard matrix multiplication of an n*n matrix of randomly generated
integer numbers from 0 to 100. The value of n is passed as an
argument with the -n flag. The default value is 200.

qsort_double:
Quick sort of an array of n randomly generated double numbers from 0
to 1000. The value of n is passed as an argument with the -n flag.
The default value is 300000.

qsort_int32:
Quick sort of an array of n randomly generated integer numbers from 0
to 50000000. The value of n is passed as an argument with the -n
flag.The default value is 300000.

qsort_string:
Quick sort of an array of 10000 randomly generated strings of size 8
(including null terminating character). The sort process is repeated
n number of times. The value of n is passed as an argument with the
-n flag. The default value is 20.

search_string:
Search for the occurrence of a small string in a much larger random
string (“needle in a hay”). The search process is repeated n number
of times and each time, a different large random string (“hay”) is
generated. The value of n can be specified using the -n flag. The
default value is 20.

Syntax:
    nightly_tests_core.py [-h] [-r REF]
    Optional arguments:
        -h, --help            Show this help message and exit
        -r REF, --reference REF
                        Reference QEMU version - Default is v5.1.0
    Example of usage:
        nightly_tests_core.py -r v5.1.0 2>log.txt

The following report includes detailed setup and execution details
of the system:
https://ahmedkrmn.github.io/TCG-Continuous-Benchmarking/QEMU-Nightly-Performance-Tests/

Signed-off-by: Ahmed Karaman <ahmedkhaledkaraman@gmail.com>
---
 tests/performance/nightly-tests/README.md     | 243 +++++
 .../source/dijkstra_double/dijkstra_double.c  | 194 ++++
 .../source/dijkstra_int32/dijkstra_int32.c    | 192 ++++
 .../source/matmult_double/matmult_double.c    | 123 +++
 .../source/matmult_int32/matmult_int32.c      | 121 +++
 .../source/qsort_double/qsort_double.c        | 104 ++
 .../source/qsort_int32/qsort_int32.c          | 103 ++
 .../source/qsort_string/qsort_string.c        | 122 +++
 .../source/search_string/search_string.c      | 110 +++
 .../scripts/nightly_tests_core.py             | 920 ++++++++++++++++++
 .../scripts/run_nightly_tests.py              | 135 +++
 .../nightly-tests/scripts/send_email.py       |  56 ++
 12 files changed, 2423 insertions(+)
 create mode 100644 tests/performance/nightly-tests/README.md
 create mode 100644 tests/performance/nightly-tests/benchmarks/source/dijkstra_double/dijkstra_double.c
 create mode 100644 tests/performance/nightly-tests/benchmarks/source/dijkstra_int32/dijkstra_int32.c
 create mode 100644 tests/performance/nightly-tests/benchmarks/source/matmult_double/matmult_double.c
 create mode 100644 tests/performance/nightly-tests/benchmarks/source/matmult_int32/matmult_int32.c
 create mode 100644 tests/performance/nightly-tests/benchmarks/source/qsort_double/qsort_double.c
 create mode 100644 tests/performance/nightly-tests/benchmarks/source/qsort_int32/qsort_int32.c
 create mode 100644 tests/performance/nightly-tests/benchmarks/source/qsort_string/qsort_string.c
 create mode 100644 tests/performance/nightly-tests/benchmarks/source/search_string/search_string.c
 create mode 100755 tests/performance/nightly-tests/scripts/nightly_tests_core.py
 create mode 100755 tests/performance/nightly-tests/scripts/run_nightly_tests.py
 create mode 100644 tests/performance/nightly-tests/scripts/send_email.py

diff --git a/tests/performance/nightly-tests/README.md b/tests/performance/nightly-tests/README.md
new file mode 100644
index 0000000000..6db3b351b3
--- /dev/null
+++ b/tests/performance/nightly-tests/README.md
@@ -0,0 +1,243 @@
+### QEMU Nightly Tests
+
+**Required settings:**
+
+Update the `GMAIL_USER` object in `send_email.py` with your credentials.
+
+For more details on how the system works, please check the [eighth report](https://ahmedkrmn.github.io/TCG-Continuous-Benchmarking/QEMU-Nightly-Performance-Tests/) of the "TCG Continuos Benchmarking" series.
+
+**Running the System:**
+
+The default reference version is v5.1.0. To specify a custom version, please use the `-r, --reference` flag.
+
+```bash
+./run_nightly_tests.py
+```
+
+**Output:**
+
+```
+Host CPU         : Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
+Host Memory      : 15.49 GB
+
+Start Time (UTC) : 2020-08-25 21:30:01
+End Time (UTC)   : 2020-08-25 22:02:37
+Execution Time   : 0:32:35.896990
+
+Status           : SUCCESS
+
+Note:
+Changes denoted by '-----' are less than 0.01%.
+
+--------------------------------------------------------
+            SUMMARY REPORT - COMMIT d1a2b51f
+--------------------------------------------------------
+                    AVERAGE RESULTS
+--------------------------------------------------------
+Target              Instructions      Latest      v5.1.0
+----------  --------------------  ----------  ----------
+aarch64            2 158 355 274       -----     +1.693%
+alpha              1 914 967 171       -----     +3.524%
+arm                8 076 402 940       -----     +2.304%
+hppa               4 261 685 987     -0.182%     +3.164%
+m68k               2 690 273 044       -----     +7.131%
+mips               1 862 033 667       -----     +2.494%
+mipsel             2 008 211 069       -----     +2.674%
+mips64             1 918 635 565       -----     +2.818%
+mips64el           2 051 565 677       -----     +3.026%
+ppc                2 480 141 217       -----     +3.107%
+ppc64              2 576 713 959       -----     +3.143%
+ppc64le            2 558 853 539       -----     +3.173%
+riscv64            1 406 704 050       -----      +2.65%
+s390x              3 158 140 046       -----     +3.118%
+sh4                2 364 449 748       -----      +3.33%
+sparc64            3 318 544 783       -----     +3.851%
+x86_64             1 775 844 158       -----     +2.156%
+--------------------------------------------------------
+
+                   DETAILED RESULTS
+--------------------------------------------------------
+Test Program: dijkstra_double
+--------------------------------------------------------
+Target              Instructions      Latest      v5.1.0
+----------  --------------------  ----------  ----------
+aarch64            3 062 583 464       -----     +1.424%
+alpha              3 191 864 698       -----     +3.696%
+arm               16 357 157 526       -----     +2.347%
+hppa               7 228 376 315     -0.139%     +3.086%
+m68k               4 294 016 587       -----     +9.692%
+mips               3 051 419 166       -----     +2.427%
+mipsel             3 231 509 618       -----     +2.869%
+mips64             3 245 837 754       -----     +2.596%
+mips64el           3 414 195 796       -----     +3.021%
+ppc                4 914 520 972     -0.041%      +4.74%
+ppc64              5 098 154 311       -----     +4.565%
+ppc64le            5 082 419 054       -----      +4.58%
+riscv64            2 192 294 915       -----     +1.955%
+s390x              4 584 503 977       -----     +2.896%
+sh4                3 949 036 447       -----     +3.464%
+sparc64            4 586 203 546       -----     +4.237%
+x86_64             2 484 092 105       -----      +1.75%
+--------------------------------------------------------
+--------------------------------------------------------
+Test Program: dijkstra_int32
+--------------------------------------------------------
+Target              Instructions      Latest      v5.1.0
+----------  --------------------  ----------  ----------
+aarch64            2 210 194 577       -----     +1.493%
+alpha              1 494 133 274       -----      +2.15%
+arm                8 262 935 967       -----     +2.665%
+hppa               5 207 318 306       -----     +3.047%
+m68k               1 725 856 962       -----     +2.527%
+mips               1 495 227 032       -----     +1.492%
+mipsel             1 497 147 869       -----     +1.479%
+mips64             1 715 388 570       -----     +1.892%
+mips64el           1 695 276 864       -----     +1.913%
+ppc                2 014 557 389       -----     +1.819%
+ppc64              2 206 267 901       -----     +2.139%
+ppc64le            2 197 998 781       -----     +2.146%
+riscv64            1 354 912 745       -----     +2.396%
+s390x              2 916 247 062       -----     +1.241%
+sh4                1 990 532 533       -----     +2.669%
+sparc64            2 872 231 051       -----     +3.758%
+x86_64             1 553 981 241       -----      +2.12%
+--------------------------------------------------------
+--------------------------------------------------------
+Test Program: matmult_double
+--------------------------------------------------------
+Target              Instructions      Latest      v5.1.0
+----------  --------------------  ----------  ----------
+aarch64            1 412 273 223       -----     +0.302%
+alpha              3 233 991 649       -----     +7.473%
+arm                8 545 173 979       -----     +1.088%
+hppa               3 483 597 802     -1.267%     +4.468%
+m68k               3 919 065 529       -----    +18.431%
+mips               2 344 774 894       -----     +4.091%
+mipsel             3 329 886 464       -----     +5.177%
+mips64             2 359 046 988       -----     +4.076%
+mips64el           3 343 664 785       -----     +5.167%
+ppc                3 209 457 051       -----     +3.246%
+ppc64              3 287 503 981       -----     +3.173%
+ppc64le            3 287 189 065       -----     +3.173%
+riscv64            1 221 603 682       -----     +0.277%
+s390x              2 874 199 923       -----     +5.827%
+sh4                3 543 943 634       -----     +6.416%
+sparc64            3 426 150 004       -----     +7.139%
+x86_64             1 248 917 276       -----     +0.322%
+--------------------------------------------------------
+--------------------------------------------------------
+Test Program: matmult_int32
+--------------------------------------------------------
+Target              Instructions      Latest      v5.1.0
+----------  --------------------  ----------  ----------
+aarch64              598 681 621       -----     +0.585%
+alpha                372 437 418       -----     +0.677%
+arm                  746 583 193       -----     +1.462%
+hppa                 674 278 359       -----     +1.183%
+m68k                 410 495 553       -----       +0.9%
+mips                 499 698 837       -----     +0.531%
+mipsel               499 500 429       -----     +0.497%
+mips64               481 554 664       -----     +0.599%
+mips64el             465 057 054       -----     +0.619%
+ppc                  341 334 603       -----     +0.944%
+ppc64                393 796 203       -----     +0.966%
+ppc64le              393 977 298       -----     +0.965%
+riscv64              351 709 769       -----     +0.785%
+s390x                494 427 384       -----     +0.599%
+sh4                  402 668 444       -----     +0.899%
+sparc64              495 952 959       -----     +1.192%
+x86_64               402 928 461       -----     +0.833%
+--------------------------------------------------------
+--------------------------------------------------------
+Test Program: qsort_double
+--------------------------------------------------------
+Target              Instructions      Latest      v5.1.0
+----------  --------------------  ----------  ----------
+aarch64            2 709 683 624       -----     +2.417%
+alpha              1 969 460 172       -----      +3.68%
+arm                8 322 998 390       -----     +2.587%
+hppa               3 188 301 995     -0.047%       +2.9%
+m68k               4 953 930 065       -----    +15.153%
+mips               2 123 919 587       -----     +3.055%
+mipsel             2 124 212 187       -----     +3.048%
+mips64             1 999 047 826       -----     +3.405%
+mips64el           1 996 426 772       -----     +3.409%
+ppc                2 819 267 902     -0.021%     +5.435%
+ppc64              2 768 186 548       -----     +5.513%
+ppc64le            2 724 803 772     -0.011%     +5.603%
+riscv64            1 638 328 937       -----     +4.021%
+s390x              2 519 081 708       -----     +3.362%
+sh4                2 595 545 154       -----     +2.994%
+sparc64            3 988 986 587       -----     +2.747%
+x86_64             2 033 468 588       -----     +3.234%
+--------------------------------------------------------
+--------------------------------------------------------
+Test Program: qsort_int32
+--------------------------------------------------------
+Target              Instructions      Latest      v5.1.0
+----------  --------------------  ----------  ----------
+aarch64            2 193 392 565       -----     +2.916%
+alpha              1 521 291 933       -----     +4.193%
+arm                3 465 445 043       -----     +2.756%
+hppa               2 280 034 340       -----     +3.821%
+m68k               1 843 189 041       -----     +3.583%
+mips               1 558 024 873       -----     +3.863%
+mipsel             1 560 583 980       -----     +3.846%
+mips64             1 563 415 749       -----     +4.412%
+mips64el           1 542 677 320       -----     +4.474%
+ppc                1 728 698 880       -----     +3.665%
+ppc64              1 842 444 545       -----     +3.555%
+ppc64le            1 791 822 067       -----     +3.661%
+riscv64            1 348 866 430       -----     +4.654%
+s390x              2 184 073 151       -----     +3.319%
+sh4                1 946 492 539       -----     +3.624%
+sparc64            3 452 215 585       -----     +2.937%
+x86_64             1 813 544 414       -----     +3.537%
+--------------------------------------------------------
+--------------------------------------------------------
+Test Program: qsort_string
+--------------------------------------------------------
+Target              Instructions      Latest      v5.1.0
+----------  --------------------  ----------  ----------
+aarch64            2 592 218 418       -----     +2.468%
+alpha              1 855 834 626       -----     +3.487%
+arm                7 347 721 165       -----     +2.682%
+hppa               4 758 753 926       -----     +3.543%
+m68k               2 376 811 462       -----     +3.567%
+mips               2 166 608 045       -----     +2.532%
+mipsel             2 163 392 541       -----     +2.528%
+mips64             2 029 251 969       -----     +3.117%
+mips64el           2 011 628 621       -----     +3.145%
+ppc                2 492 942 463       -----     +2.673%
+ppc64              2 464 702 554       -----     +2.488%
+ppc64le            2 445 253 307       -----     +2.505%
+riscv64            1 625 053 328       -----     +3.953%
+s390x              4 194 608 798       -----     +6.623%
+sh4                2 164 142 539       -----     +3.166%
+sparc64            4 299 516 539       -----     +4.065%
+x86_64             2 940 456 780       -----     +2.649%
+--------------------------------------------------------
+--------------------------------------------------------
+Test Program: search_string
+--------------------------------------------------------
+Target              Instructions      Latest      v5.1.0
+----------  --------------------  ----------  ----------
+aarch64            2 487 814 704       -----      +1.94%
+alpha              1 680 723 605       -----     +2.835%
+arm               11 563 208 260       -----     +2.848%
+hppa               7 272 826 858       -----     +3.263%
+m68k               1 998 819 159       -----     +3.198%
+mips               1 656 596 909       -----     +1.959%
+mipsel             1 659 455 464       -----     +1.947%
+mips64             1 955 541 001       -----     +2.447%
+mips64el           1 943 598 207       -----     +2.462%
+ppc                2 320 350 477       -----     +2.332%
+ppc64              2 552 655 634       -----     +2.742%
+ppc64le            2 547 364 971       -----     +2.748%
+riscv64            1 520 862 601       -----     +3.159%
+s390x              5 497 978 370       -----     +1.078%
+sh4                2 323 236 696       -----      +3.41%
+sparc64            3 427 101 999       -----      +4.73%
+x86_64             1 729 364 402       -----     +2.806%
+--------------------------------------------------------
+```
diff --git a/tests/performance/nightly-tests/benchmarks/source/dijkstra_double/dijkstra_double.c b/tests/performance/nightly-tests/benchmarks/source/dijkstra_double/dijkstra_double.c
new file mode 100644
index 0000000000..9c0bb804ac
--- /dev/null
+++ b/tests/performance/nightly-tests/benchmarks/source/dijkstra_double/dijkstra_double.c
@@ -0,0 +1,194 @@
+/*
+ *  Source file of a benchmark program involving calculations of the
+ *  shortest distances between a source node and all other nodes in a
+ *  graph of n nodes in which all nxn distances are defined as "double".
+ *  The number n can be given via command line, and the default is 2000.
+ *  The algorithm used is Dijsktra's.
+ *
+ *  This file is a part of the project "TCG Continuous Benchmarking".
+ *
+ *  Copyright (C) 2020  Ahmed Karaman <ahmedkhaledkaraman@gmail.com>
+ *  Copyright (C) 2020  Aleksandar Markovic <aleksandar.qemu.devel@gmail.com>
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <float.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Number of columns and rows in all matrixes*/
+#define DEFAULT_NODE_COUNT      2000
+#define MIN_NODE_COUNT          3
+#define MAX_NODE_COUNT          10000
+
+
+int32_t closest_index(int32_t count, double *distances, bool *flags)
+{
+    int32_t closest;
+    double minimum = DBL_MAX;
+
+    for (size_t i = 0; i < count; i++) {
+        if (flags[i] == false && distances[i] <= minimum) {
+            closest = i;
+            minimum = distances[i];
+        }
+    }
+
+    return closest;
+}
+
+/**
+ * Calculate the shortest distances from the source node using Dijkstra method.
+ * @param (out) distances  An array of shortest distances from the source node.
+ * @param (out) via  An array of nodes needed to be taken as the the last
+ *                   before destination, for each destination.
+ * @param (out) eccent  Eccentricity of the source node.
+ * @param (in) count  The number of nodes.
+ * @param (in) source  Source node.
+ * @param (in) matrix  Distance matrix.
+ */
+void find_shortest_distances(double *distances, int32_t *via, double *eccent,
+                             int32_t count, int32_t source, double **matrix)
+{
+    bool *flags;
+
+    flags = (bool *)malloc(count * sizeof(bool));
+
+    for (size_t i = 0; i < count; i++) {
+        distances[i] = DBL_MAX;
+        flags[i] = false;
+    }
+
+    distances[source] = 0.0;
+    via[source] = source;
+
+    for (size_t i = 0; i < count - 1; i++) {
+        int32_t closest = closest_index(count, distances, flags);
+        flags[closest] = true;
+        for (size_t j = 0; j < count; j++) {
+            if ((!flags[j]) &&
+                    (matrix[closest][j]) &&
+                    (distances[closest] != DBL_MAX) &&
+                    (distances[j] > distances[closest] + matrix[closest][j])) {
+                distances[j] = distances[closest] + matrix[closest][j];
+                via[j] = closest;
+            }
+        }
+    }
+
+    *eccent = 0;
+    for (size_t i = 0; i < count; i++) {
+        if (*eccent < distances[i]) {
+            *eccent = distances[i];
+        }
+    }
+
+    free(flags);
+}
+
+
+void main(int argc, char *argv[])
+{
+    double **distance_matrix;
+    double *shortest_distances;
+    int32_t *via_node;
+    int32_t node_count = DEFAULT_NODE_COUNT;
+    int32_t source_node = 0;
+    double node_eccentricity = 0.0;
+    double range_factor = 999.0 / (double)(RAND_MAX);
+    int32_t option;
+
+    /* Parse command line options */
+    while ((option = getopt(argc, argv, "n:")) != -1) {
+        if (option == 'n') {
+            int32_t user_node_count = atoi(optarg);
+
+            /* Check if the value is a string or zero */
+            if (user_node_count == 0) {
+                fprintf(stderr, "Error ... Invalid value for option '-n'.\n");
+                exit(EXIT_FAILURE);
+            }
+            /* Check if the value is a negative number */
+            if (user_node_count < MIN_NODE_COUNT) {
+                fprintf(stderr, "Error ... Value for option '-n' cannot be a "
+                                "number less than %d.\n", MIN_NODE_COUNT);
+                exit(EXIT_FAILURE);
+            }
+            /* Check if the value is too large */
+            if (user_node_count > MAX_NODE_COUNT) {
+                fprintf(stderr, "Error ... Value for option '-n' cannot be "
+                                "more than %d.\n", MAX_NODE_COUNT);
+                exit(EXIT_FAILURE);
+            }
+            node_count = user_node_count;
+        } else {
+            exit(EXIT_FAILURE);
+        }
+    }
+
+    /* Allocate the memory space for all matrixes */
+    distance_matrix = (double **)malloc(node_count * sizeof(double *));
+    for (size_t i = 0; i < node_count; i++) {
+        distance_matrix[i] = (double *)malloc(node_count * sizeof(double));
+    }
+    shortest_distances = (double *)malloc(node_count * sizeof(double));
+    via_node = (int32_t *)malloc(node_count * sizeof(int32_t));
+
+    /* Initialize helper arrays and populate distance_matrix */
+    srand(1);
+    for (size_t i = 0; i < node_count; i++) {
+        shortest_distances[i] = 0.0;
+        via_node[i] = -1;
+        distance_matrix[i][i] = 0.0;
+    }
+    for (size_t i = 0; i < node_count; i++) {
+        for (size_t j = i + 1; j < node_count; j++) {
+            distance_matrix[i][j] = 1.0 + range_factor * (double)rand();
+            distance_matrix[j][i] = distance_matrix[i][j];
+        }
+    }
+
+    find_shortest_distances(shortest_distances, via_node, &node_eccentricity,
+                            node_count, source_node, distance_matrix);
+
+    /* Control printing */
+    printf("CONTROL RESULT:\n");
+    printf(" Distance matrix (top left part):\n");
+    for (size_t i = 0; i < 3; i++) {
+        for (size_t j = 0; j < 3; j++) {
+            printf("    %7.2f", distance_matrix[i][j]);
+        }
+        printf("\n");
+    }
+    printf(" Source: %d (eccentricity: %f)\n",
+           source_node, node_eccentricity);
+    printf(" Destination   Distance   Via Node\n");
+    for (size_t i = 0; i < 3; i++) {
+        printf("  %5d       %7.2f       %4d\n",
+               i, shortest_distances[i], via_node[i]);
+    }
+
+    /* Free all previously allocated space */
+    for (size_t i = 0; i < node_count; i++) {
+        free(distance_matrix[i]);
+    }
+    free(distance_matrix);
+    free(shortest_distances);
+    free(via_node);
+}
diff --git a/tests/performance/nightly-tests/benchmarks/source/dijkstra_int32/dijkstra_int32.c b/tests/performance/nightly-tests/benchmarks/source/dijkstra_int32/dijkstra_int32.c
new file mode 100644
index 0000000000..2663cde943
--- /dev/null
+++ b/tests/performance/nightly-tests/benchmarks/source/dijkstra_int32/dijkstra_int32.c
@@ -0,0 +1,192 @@
+/*
+ *  Source file of a benchmark program involving calculations of the
+ *  shortest distances between a source node and all other nodes in a
+ *  graph of n nodes in which all nxn distances are defined as "int32".
+ *  The number n can be given via command line, and the default is 2000.
+ *  The algorithm used is Dijsktra's.
+ *
+ *  This file is a part of the project "TCG Continuous Benchmarking".
+ *
+ *  Copyright (C) 2020  Ahmed Karaman <ahmedkhaledkaraman@gmail.com>
+ *  Copyright (C) 2020  Aleksandar Markovic <aleksandar.qemu.devel@gmail.com>
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <limits.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Number of columns and rows in all matrixes*/
+#define DEFAULT_NODE_COUNT      2000
+#define MIN_NODE_COUNT          3
+#define MAX_NODE_COUNT          10000
+
+
+int32_t closest_index(int32_t count, int32_t *distances, bool *flags)
+{
+    int32_t closest;
+    int32_t minimum = INT_MAX;
+
+    for (size_t i = 0; i < count; i++) {
+        if (flags[i] == false && distances[i] <= minimum) {
+            closest = i;
+            minimum = distances[i];
+        }
+    }
+
+    return closest;
+}
+
+/**
+ * Calculate the shortest distances from the source node using Dijkstra method.
+ * @param (out) distances  An array of shortest distances from the source node.
+ * @param (out) via  An array of nodes needed to be taken as the the last
+ *                   before destination, for each destination.
+ * @param (out) eccent  Eccentricity of the source node.
+ * @param (in) count  The number of nodes.
+ * @param (in) source  Source node.
+ * @param (in) matrix  Distance matrix.
+ */
+void find_shortest_distances(int32_t *distances, int32_t *via, int32_t *eccent,
+                             int32_t count, int32_t source, int32_t **matrix)
+{
+    bool *flags;
+
+    flags = (bool *)malloc(count * sizeof(bool));
+
+    for (size_t i = 0; i < count; i++) {
+        distances[i] = INT_MAX;
+        flags[i] = false;
+    }
+
+    distances[source] = 0;
+    via[source] = source;
+
+    for (size_t i = 0; i < count - 1; i++) {
+        int32_t closest = closest_index(count, distances, flags);
+        flags[closest] = true;
+        for (size_t j = 0; j < count; j++) {
+            if ((!flags[j]) &&
+                    (matrix[closest][j]) &&
+                    (distances[closest] != INT_MAX) &&
+                    (distances[j] > distances[closest] + matrix[closest][j])) {
+                distances[j] = distances[closest] + matrix[closest][j];
+                via[j] = closest;
+            }
+        }
+    }
+
+    *eccent = 0;
+    for (size_t i = 0; i < count; i++) {
+        if (*eccent < distances[i]) {
+            *eccent = distances[i];
+        }
+    }
+
+    free(flags);
+}
+
+
+void main(int argc, char *argv[])
+{
+    int32_t **distance_matrix;
+    int32_t *shortest_distances;
+    int32_t *via_node;
+    int32_t node_count = DEFAULT_NODE_COUNT;
+    int32_t source_node = 0;
+    int32_t node_eccentricity = 0;
+    int32_t option;
+
+    /* Parse command line options */
+    while ((option = getopt(argc, argv, "n:")) != -1) {
+        if (option == 'n') {
+            int32_t user_node_count = atoi(optarg);
+
+            /* Check if the value is a string or zero */
+            if (user_node_count == 0) {
+                fprintf(stderr, "Error ... Invalid value for option '-n'.\n");
+                exit(EXIT_FAILURE);
+            }
+            /* Check if the value is a negative number */
+            if (user_node_count < MIN_NODE_COUNT) {
+                fprintf(stderr, "Error ... Value for option '-n' cannot be a "
+                                "number less than %d.\n", MIN_NODE_COUNT);
+                exit(EXIT_FAILURE);
+            }
+            /* Check if the value is too large */
+            if (user_node_count > MAX_NODE_COUNT) {
+                fprintf(stderr, "Error ... Value for option '-n' cannot be "
+                                "more than %d.\n", MAX_NODE_COUNT);
+                exit(EXIT_FAILURE);
+            }
+            node_count = user_node_count;
+        } else {
+            exit(EXIT_FAILURE);
+        }
+    }
+
+    /* Allocate the memory space for all matrixes */
+    distance_matrix = (int32_t **)malloc(node_count * sizeof(int32_t *));
+    for (size_t i = 0; i < node_count; i++) {
+        distance_matrix[i] = (int32_t *)malloc(node_count * sizeof(int32_t));
+    }
+    shortest_distances = (int32_t *)malloc(node_count * sizeof(int32_t));
+    via_node = (int32_t *)malloc(node_count * sizeof(int32_t));
+
+    /* Initialize helper arrays and populate distance_matrix */
+    srand(1);
+    for (size_t i = 0; i < node_count; i++) {
+        shortest_distances[i] = 0;
+        via_node[i] = -1;
+        distance_matrix[i][i] = 0;
+    }
+    for (size_t i = 0; i < node_count; i++) {
+        for (size_t j = i + 1; j < node_count; j++) {
+            distance_matrix[i][j] = 1 + (rand()) / (RAND_MAX / 999);
+            distance_matrix[j][i] = distance_matrix[i][j];
+        }
+    }
+
+    find_shortest_distances(shortest_distances, via_node, &node_eccentricity,
+                            node_count, source_node, distance_matrix);
+
+    /* Control printing */
+    printf("CONTROL RESULT:\n");
+    printf(" Distance matrix (top left part):\n");
+    for (size_t i = 0; i < 3; i++) {
+        for (size_t j = 0; j < 3; j++) {
+            printf("    %6d", distance_matrix[i][j]);
+        }
+        printf("\n");
+    }
+    printf(" Source: %d (eccentricity: %d)\n",
+           source_node, node_eccentricity);
+    printf(" Destination   Distance   Via Node\n");
+    for (size_t i = 0; i < 3; i++) {
+        printf("  %5d          %3d        %4d\n",
+               i, shortest_distances[i], via_node[i]);
+    }
+
+    /* Free all previously allocated space */
+    for (size_t i = 0; i < node_count; i++) {
+        free(distance_matrix[i]);
+    }
+    free(distance_matrix);
+    free(shortest_distances);
+    free(via_node);
+}
diff --git a/tests/performance/nightly-tests/benchmarks/source/matmult_double/matmult_double.c b/tests/performance/nightly-tests/benchmarks/source/matmult_double/matmult_double.c
new file mode 100644
index 0000000000..42bbb4717a
--- /dev/null
+++ b/tests/performance/nightly-tests/benchmarks/source/matmult_double/matmult_double.c
@@ -0,0 +1,123 @@
+/*
+ *  Source file of a benchmark program involving calculations of
+ *  a product of two matrixes nxn whose elements are "double". The
+ *  number n can be given via command line, and the default is 200.
+ *
+ *  This file is a part of the project "TCG Continuous Benchmarking".
+ *
+ *  Copyright (C) 2020  Ahmed Karaman <ahmedkhaledkaraman@gmail.com>
+ *  Copyright (C) 2020  Aleksandar Markovic <aleksandar.qemu.devel@gmail.com>
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Number of columns and rows in all matrixes*/
+#define DEFAULT_MATRIX_SIZE     200
+#define MIN_MATRIX_SIZE         2
+#define MAX_MATRIX_SIZE         200000
+
+void main(int argc, char *argv[])
+{
+    double **matrix_a;
+    double **matrix_b;
+    double **matrix_res;
+    size_t i;
+    size_t j;
+    size_t k;
+    int32_t matrix_size = DEFAULT_MATRIX_SIZE;
+    int32_t option;
+    double range_factor = 100.0 / (double)(RAND_MAX);
+
+
+    /* Parse command line options */
+    while ((option = getopt(argc, argv, "n:")) != -1) {
+        if (option == 'n') {
+            int32_t user_matrix_size = atoi(optarg);
+
+            /* Check if the value is a string or zero */
+            if (user_matrix_size == 0) {
+                fprintf(stderr, "Error ... Invalid value for option '-n'.\n");
+                exit(EXIT_FAILURE);
+            }
+            /* Check if the value is a negative number */
+            if (user_matrix_size < MIN_MATRIX_SIZE) {
+                fprintf(stderr, "Error ... Value for option '-n' cannot be a "
+                                "number less than %d.\n", MIN_MATRIX_SIZE);
+                exit(EXIT_FAILURE);
+            }
+            /* Check if the value is too large */
+            if (user_matrix_size > MAX_MATRIX_SIZE) {
+                fprintf(stderr, "Error ... Value for option '-n' cannot be "
+                                "more than %d.\n", MAX_MATRIX_SIZE);
+                exit(EXIT_FAILURE);
+            }
+            matrix_size = user_matrix_size;
+        } else {
+            exit(EXIT_FAILURE);
+        }
+    }
+
+    /* Allocate the memory space for all matrixes */
+    matrix_a = (double **)malloc(matrix_size * sizeof(double *));
+    for (i = 0; i < matrix_size; i++) {
+        matrix_a[i] = (double *)malloc(matrix_size * sizeof(double));
+    }
+    matrix_b = (double **)malloc(matrix_size * sizeof(double *));
+    for (i = 0; i < matrix_size; i++) {
+        matrix_b[i] = (double *)malloc(matrix_size * sizeof(double));
+    }
+    matrix_res = (double **)malloc(matrix_size * sizeof(double *));
+    for (i = 0; i < matrix_size; i++) {
+        matrix_res[i] = (double *)malloc(matrix_size * sizeof(double));
+    }
+
+    /* Populate matrix_a and matrix_b with random numbers */
+    srand(1);
+    for (i = 0; i < matrix_size; i++) {
+        for (j = 0; j < matrix_size; j++) {
+            matrix_a[i][j] = range_factor * (double)rand();
+            matrix_b[i][j] = range_factor * (double)rand();
+        }
+    }
+
+    /* Calculate the product of two matrixes */
+    for (i = 0; i < matrix_size; i++) {
+        for (j = 0; j < matrix_size; j++) {
+            matrix_res[i][j] = 0.0;
+            for (k = 0; k < matrix_size; k++) {
+                matrix_res[i][j] += matrix_a[i][k] * matrix_b[k][j];
+            }
+        }
+    }
+
+    /* Control printing */
+    printf("CONTROL RESULT:\n");
+    printf(" %f %f\n", matrix_res[0][0], matrix_res[0][1]);
+    printf(" %f %f\n", matrix_res[1][0], matrix_res[1][1]);
+
+    /* Free all previously allocated space */
+    for (i = 0; i < matrix_size; i++) {
+        free(matrix_a[i]);
+        free(matrix_b[i]);
+        free(matrix_res[i]);
+    }
+    free(matrix_a);
+    free(matrix_b);
+    free(matrix_res);
+}
diff --git a/tests/performance/nightly-tests/benchmarks/source/matmult_int32/matmult_int32.c b/tests/performance/nightly-tests/benchmarks/source/matmult_int32/matmult_int32.c
new file mode 100644
index 0000000000..29a6eb000d
--- /dev/null
+++ b/tests/performance/nightly-tests/benchmarks/source/matmult_int32/matmult_int32.c
@@ -0,0 +1,121 @@
+/*
+ *  Source file of a benchmark program involving calculations of
+ *  a product of two matrixes nxn whose elements are "int32_t". The
+ *  number n can be given via command line, and the default is 200.
+ *
+ *  This file is a part of the project "TCG Continuous Benchmarking".
+ *
+ *  Copyright (C) 2020  Ahmed Karaman <ahmedkhaledkaraman@gmail.com>
+ *  Copyright (C) 2020  Aleksandar Markovic <aleksandar.qemu.devel@gmail.com>
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Number of columns and rows in all matrixes*/
+#define DEFAULT_MATRIX_SIZE     200
+#define MIN_MATRIX_SIZE         2
+#define MAX_MATRIX_SIZE         200000
+
+void main(int argc, char *argv[])
+{
+    int32_t **matrix_a;
+    int32_t **matrix_b;
+    int32_t **matrix_res;
+    size_t i;
+    size_t j;
+    size_t k;
+    int32_t matrix_size = DEFAULT_MATRIX_SIZE;
+    int32_t option;
+
+    /* Parse command line options */
+    while ((option = getopt(argc, argv, "n:")) != -1) {
+        if (option == 'n') {
+            int32_t user_matrix_size = atoi(optarg);
+
+            /* Check if the value is a string or zero */
+            if (user_matrix_size == 0) {
+                fprintf(stderr, "Error ... Invalid value for option '-n'.\n");
+                exit(EXIT_FAILURE);
+            }
+            /* Check if the value is a negative number */
+            if (user_matrix_size < MIN_MATRIX_SIZE) {
+                fprintf(stderr, "Error ... Value for option '-n' cannot be a "
+                                "number less than %d.\n", MIN_MATRIX_SIZE);
+                exit(EXIT_FAILURE);
+            }
+            /* Check if the value is too large */
+            if (user_matrix_size > MAX_MATRIX_SIZE) {
+                fprintf(stderr, "Error ... Value for option '-n' cannot be "
+                                "more than %d.\n", MAX_MATRIX_SIZE);
+                exit(EXIT_FAILURE);
+            }
+            matrix_size = user_matrix_size;
+        } else {
+            exit(EXIT_FAILURE);
+        }
+    }
+
+    /* Allocate the memory space for all matrixes */
+    matrix_a = (int32_t **)malloc(matrix_size * sizeof(int32_t *));
+    for (i = 0; i < matrix_size; i++) {
+        matrix_a[i] = (int32_t *)malloc(matrix_size * sizeof(int32_t));
+    }
+    matrix_b = (int32_t **)malloc(matrix_size * sizeof(int32_t *));
+    for (i = 0; i < matrix_size; i++) {
+        matrix_b[i] = (int32_t *)malloc(matrix_size * sizeof(int32_t));
+    }
+    matrix_res = (int32_t **)malloc(matrix_size * sizeof(int32_t *));
+    for (i = 0; i < matrix_size; i++) {
+        matrix_res[i] = (int32_t *)malloc(matrix_size * sizeof(int32_t));
+    }
+
+    /* Populate matrix_a and matrix_b with random numbers */
+    srand(1);
+    for (i = 0; i < matrix_size; i++) {
+        for (j = 0; j < matrix_size; j++) {
+            matrix_a[i][j] = (rand()) / (RAND_MAX / 100);
+            matrix_b[i][j] = (rand()) / (RAND_MAX / 100);
+        }
+    }
+
+    /* Calculate the product of two matrixes */
+    for (i = 0; i < matrix_size; i++) {
+        for (j = 0; j < matrix_size; j++) {
+            matrix_res[i][j] = 0;
+            for (k = 0; k < matrix_size; k++) {
+                matrix_res[i][j] += matrix_a[i][k] * matrix_b[k][j];
+            }
+        }
+    }
+
+    /* Control printing */
+    printf("CONTROL RESULT:\n");
+    printf(" %d %d\n", matrix_res[0][0], matrix_res[0][1]);
+    printf(" %d %d\n", matrix_res[1][0], matrix_res[1][1]);
+
+    /* Free all previously allocated space */
+    for (i = 0; i < matrix_size; i++) {
+        free(matrix_a[i]);
+        free(matrix_b[i]);
+        free(matrix_res[i]);
+    }
+    free(matrix_a);
+    free(matrix_b);
+    free(matrix_res);
+}
diff --git a/tests/performance/nightly-tests/benchmarks/source/qsort_double/qsort_double.c b/tests/performance/nightly-tests/benchmarks/source/qsort_double/qsort_double.c
new file mode 100644
index 0000000000..efc1b2eee1
--- /dev/null
+++ b/tests/performance/nightly-tests/benchmarks/source/qsort_double/qsort_double.c
@@ -0,0 +1,104 @@
+/*
+ *  Source file of a benchmark program involving sorting of an array
+ *  of length n whose elements are "double". The default value for n
+ *  is 300000, and it can be set via command line as well.
+ *
+ *  This file is a part of the project "TCG Continuous Benchmarking".
+ *
+ *  Copyright (C) 2020  Ahmed Karaman <ahmedkhaledkaraman@gmail.com>
+ *  Copyright (C) 2020  Aleksandar Markovic <aleksandar.qemu.devel@gmail.com>
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Number of elements in the array to be sorted */
+#define DEFAULT_ARRAY_LEN       300000
+#define MIN_ARRAY_LEN           3
+#define MAX_ARRAY_LEN           30000000
+
+/* Upper limit used for generation of random numbers */
+#define UPPER_LIMIT             1000.0
+
+/* Comparison function passed to qsort() */
+static int compare(const void *a, const void *b)
+{
+    if (*(const double *)a > *(const double *)b) {
+        return 1;
+    } else if (*(const double *)a < *(const double *)b) {
+        return -1;
+    }
+    return 0;
+}
+
+void main(int argc, char *argv[])
+{
+    double *array_to_be_sorted;
+    int32_t array_len = DEFAULT_ARRAY_LEN;
+    int32_t option;
+    double range_factor = UPPER_LIMIT / (double)(RAND_MAX);
+
+    /* Parse command line options */
+    while ((option = getopt(argc, argv, "n:")) != -1) {
+        if (option == 'n') {
+            int32_t user_array_len = atoi(optarg);
+
+            /* Check if the value is a string or zero */
+            if (user_array_len == 0) {
+                fprintf(stderr, "Error ... Invalid value for option '-n'.\n");
+                exit(EXIT_FAILURE);
+            }
+            /* Check if the value is a negative number */
+            if (user_array_len < MIN_ARRAY_LEN) {
+                fprintf(stderr, "Error ... Value for option '-n' cannot be a "
+                                "number less than %d.\n", MIN_ARRAY_LEN);
+                exit(EXIT_FAILURE);
+            }
+            /* Check if the value is too large */
+            if (user_array_len > MAX_ARRAY_LEN) {
+                fprintf(stderr, "Error ... Value for option '-n' cannot be "
+                                "more than %d.\n", MAX_ARRAY_LEN);
+                exit(EXIT_FAILURE);
+            }
+            array_len = user_array_len;
+        } else {
+            exit(EXIT_FAILURE);
+        }
+    }
+
+    /* Allocate the memory space for the array */
+    array_to_be_sorted = (double *) malloc(array_len * sizeof(double));
+
+    /* Populate the_array with random numbers */
+    srand(1);
+    for (size_t i = 0; i < array_len; i++) {
+        array_to_be_sorted[i] = range_factor * (double)rand();
+    }
+
+    /* Sort the_array using qsort() */
+    qsort(array_to_be_sorted, array_len, sizeof(array_to_be_sorted[0]),
+          compare);
+
+    /* Control printing */
+    printf("CONTROL RESULT:\n");
+    printf("%14.10f %14.10f %14.10f\n",
+           array_to_be_sorted[0], array_to_be_sorted[1], array_to_be_sorted[2]);
+
+    /* Free all previously allocated space */
+    free(array_to_be_sorted);
+}
diff --git a/tests/performance/nightly-tests/benchmarks/source/qsort_int32/qsort_int32.c b/tests/performance/nightly-tests/benchmarks/source/qsort_int32/qsort_int32.c
new file mode 100644
index 0000000000..76ca9c3490
--- /dev/null
+++ b/tests/performance/nightly-tests/benchmarks/source/qsort_int32/qsort_int32.c
@@ -0,0 +1,103 @@
+/*
+ *  Source file of a benchmark program involving sorting of an array
+ *  of length n whose elements are "int32_t". The default value for n
+ *  is 300000, and it can be set via command line as well.
+ *
+ *  This file is a part of the project "TCG Continuous Benchmarking".
+ *
+ *  Copyright (C) 2020  Ahmed Karaman <ahmedkhaledkaraman@gmail.com>
+ *  Copyright (C) 2020  Aleksandar Markovic <aleksandar.qemu.devel@gmail.com>
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Number of elements in the array to be sorted */
+#define DEFAULT_ARRAY_LEN       300000
+#define MIN_ARRAY_LEN           3
+#define MAX_ARRAY_LEN           30000000
+
+/* Upper limit used for generation of random numbers */
+#define UPPER_LIMIT             50000000
+
+/* Comparison function passed to qsort() */
+static int compare(const void *a, const void *b)
+{
+    if (*(const int32_t *)a > *(const int32_t *)b) {
+        return 1;
+    } else if (*(const int32_t *)a < *(const int32_t *)b) {
+        return -1;
+    }
+    return 0;
+}
+
+void main(int argc, char *argv[])
+{
+    int32_t *array_to_be_sorted;
+    int32_t array_len = DEFAULT_ARRAY_LEN;
+    int32_t option;
+
+    /* Parse command line options */
+    while ((option = getopt(argc, argv, "n:")) != -1) {
+        if (option == 'n') {
+            int32_t user_array_len = atoi(optarg);
+
+            /* Check if the value is a string or zero */
+            if (user_array_len == 0) {
+                fprintf(stderr, "Error ... Invalid value for option '-n'.\n");
+                exit(EXIT_FAILURE);
+            }
+            /* Check if the value is a negative number */
+            if (user_array_len < MIN_ARRAY_LEN) {

reply via email to

[Prev in Thread] Current Thread [Next in Thread]