Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/trusty/trusty/kernel/app/memorylatencybench/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 5 kB image not shown  

Quelle  main.c

  Sprache: C
 

/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#define TLOG_TAG "memlatency"

#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include <arch/defines.h>
#include <trusty_benchmark.h>
#include <uapi/err.h>

#define BLOCK_SIZE_BYTES (CACHE_LINE * 4)
#define STRUCT_NPAD (BLOCK_SIZE_BYTES) / sizeof(uintptr_t)
#define MAX_WORKING_SET_SZ 16777216

static const uint64_t working_set_sizes[] = {
        BLOCK_SIZE_BYTES,
        512,
        1024,
        2048,
        4096,
        8192,
        16384,
        32768,
        65536,
        131072,
        262144,
        524288,
        1048576,
        2097152,
        4194304,
        8388608,
        MAX_WORKING_SET_SZ,
};

typedef union memlatency_state_t {
    union memlatency_state_t* next;
    uintptr_t pad[STRUCT_NPAD];
} memlatency_state_t;

static memlatency_state_t* memlatency_state_start;

static size_t nb_blocks = MAX_WORKING_SET_SZ / sizeof(memlatency_state_t);

static void get_param_name_cb_fixed(char* buf,
                                    size_t buf_size,
                                    size_t param_idx) {
    snprintf(buf, buf_size,
             "%" PRIu64 " Bytes working size in blocks of %zu Bytes",
             working_set_sizes[param_idx], sizeof(memlatency_state_t));
}

static void get_formatted_value_cb(char* buf,
                                   size_t buf_size,
                                   int64_t value,
                                   const char* metric_name) {
    if (strcmp("time_micro_seconds", metric_name) == 0) {
        int64_t mic_sec = value / 1000;
        int64_t n_sec = value % 1000;

        snprintf(buf, buf_size, "%" PRId64 ".%03" PRId64 "", mic_sec, n_sec);
    } else {
        snprintf(buf, buf_size, "%" PRId64, value);
    }
}

static uint64_t mem_lat_pmu_evt_arr[] = {PMU_EV_CPU_CYCLES,
                                         PMU_EV_INST_RETIRED};

BENCH_SETUP(memlatency) {
    BENCH_INIT_PMU(mem_lat_pmu_evt_arr);
    trusty_bench_get_param_name_cb = &get_param_name_cb_fixed;
    trusty_bench_get_formatted_value_cb = &get_formatted_value_cb;
    memlatency_state_start =
            memalign(CACHE_LINE, nb_blocks * sizeof(memlatency_state_t));

    if (memlatency_state_start == NULL) {
        TLOGE("Failed to Allocate memory for memlatency_state!");
        return ERR_NO_MEMORY;
    }

    memset((uint8_t*)memlatency_state_start, 0,
           nb_blocks * sizeof(memlatency_state_t));

    for (size_t idx = 0; idx < nb_blocks - 1; ++idx) {
        memlatency_state_start[idx].next = &memlatency_state_start[idx + 1];
    }

    static_assert(sizeof(memlatency_state_t) == BLOCK_SIZE_BYTES);

    return NO_ERROR;
}

BENCH_TEARDOWN(memlatency) {
    free(memlatency_state_start);
    memlatency_state_start = NULL;
}

BENCH(memlatency, latency_read, 20, working_set_sizes) {
    uint64_t sz = working_set_sizes[bench_get_param_idx()];
    uint64_t nb_blocks = sz / BLOCK_SIZE_BYTES;
    uint64_t loops = 10 * (MAX_WORKING_SET_SZ / sz);

    ASSERT_GT(nb_blocks, 0);

    while (loops > 0) {
        --loops;
        volatile union memlatency_state_t* block = memlatency_state_start;

        for (size_t idx = 0; idx < nb_blocks; idx++) {
            /* To make sure we are not overwriting next block Address */
            static_assert(sizeof(uintptr_t) == __SIZEOF_POINTER__);
            block = block->next;
        }
    }

    return NO_ERROR;
test_abort:
    return ERR_GENERIC;
}

BENCH(memlatency, latency_write, 20, working_set_sizes) {
    uint64_t sz = working_set_sizes[bench_get_param_idx()];
    uint64_t nb_blocks = sz / BLOCK_SIZE_BYTES;
    uint64_t loops = 10 * (MAX_WORKING_SET_SZ / sz);

    ASSERT_GT(nb_blocks, 0);

    while (loops > 0) {
        --loops;
        union memlatency_state_t* block = memlatency_state_start;

        for (size_t idx = 0; idx < nb_blocks; idx++) {
            /* To make sure we are not overwriting next block Address */
            static_assert(sizeof(uintptr_t) == __SIZEOF_POINTER__);
            (block + idx)->pad[1] = idx + sz;
        }
    }

    return NO_ERROR;
test_abort:
    return ERR_GENERIC;
}

BENCH_RESULT(memlatency, latency_read, time_micro_seconds) {
    return bench_get_duration_ns();
}

BENCH_RESULT(memlatency, latency_write, time_micro_seconds) {
    return bench_get_duration_ns();
}

BENCH_RESULT(memlatency, latency_read, cycle_counter_0) {
    return bench_get_pmu_cnt(0);
}

BENCH_RESULT(memlatency, latency_read, cycle_counter) {
    return bench_get_pmu_cnt(1);
}

BENCH_RESULT(memlatency, latency_read, inst_retired) {
    return bench_get_pmu_cnt(2);
}

PORT_TEST(memlatency, "com.android.kernel.memorylatency.bench");

Messung V0.5 in Prozent
C=81 H=81 G=80

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet am  2026-06-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.