blob: 38435098e9078c81e8ab3d53c03b29200e2e6266 [file] [log] [blame]
/* Copyright 2023 The ChromiumOS Authors
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "shared_mem.h"
#include "test_util.h"
#include "timer.h"
test_static int benchmark_unaligned_access()
{
int i;
timestamp_t t0, t1, t2, t3;
alignas(uint32_t) volatile int8_t dst[2 * sizeof(uint32_t)];
volatile uint32_t *const unaligned = (volatile uint32_t *)(dst + 1);
volatile uint32_t *const aligned = (volatile uint32_t *)dst;
ccprintf("dst=0x%p\n", dst);
ccprintf("unaligned=0x%p and aligned=0x%p\n", unaligned, aligned);
const int iteration = 1000000;
const int unrollcount = 20;
for (i = 0; i < sizeof(dst); ++i) {
dst[i] = 0;
}
t0 = get_time();
for (i = 0; i < iteration; ++i) {
/* unaligned */
// Our little write operation is much less significant than
// the loop variable updating, so we need to unroll the loop a
// a bit to make each loop action more significant.
*unaligned = 0xFEF8F387;
*unaligned = 0xFEF8F387;
*unaligned = 0xFEF8F387;
*unaligned = 0xFEF8F387;
*unaligned = 0xFEF8F387;
*unaligned = 0xFEF8F387;
*unaligned = 0xFEF8F387;
*unaligned = 0xFEF8F387;
*unaligned = 0xFEF8F387;
*unaligned = 0xFEF8F387;
*unaligned = 0xFEF8F387;
*unaligned = 0xFEF8F387;
*unaligned = 0xFEF8F387;
*unaligned = 0xFEF8F387;
*unaligned = 0xFEF8F387;
*unaligned = 0xFEF8F387;
*unaligned = 0xFEF8F387;
*unaligned = 0xFEF8F387;
*unaligned = 0xFEF8F387;
*unaligned = 0xFEF8F387;
}
t1 = get_time();
uint64_t unaligned_time = t1.val - t0.val;
ccprintf("Unaligned took %" PRId64 "us, which is %" PRId64
"ns per iteration.\n",
unaligned_time,
(1000 * unaligned_time) / (iteration * unrollcount));
for (i = 0; i < sizeof(dst); ++i) {
dst[i] = 0;
}
t2 = get_time();
for (i = 0; i < iteration; ++i) {
/* aligned */
*aligned = 0xFEF8F387;
*aligned = 0xFEF8F387;
*aligned = 0xFEF8F387;
*aligned = 0xFEF8F387;
*aligned = 0xFEF8F387;
*aligned = 0xFEF8F387;
*aligned = 0xFEF8F387;
*aligned = 0xFEF8F387;
*aligned = 0xFEF8F387;
*aligned = 0xFEF8F387;
*aligned = 0xFEF8F387;
*aligned = 0xFEF8F387;
*aligned = 0xFEF8F387;
*aligned = 0xFEF8F387;
*aligned = 0xFEF8F387;
*aligned = 0xFEF8F387;
*aligned = 0xFEF8F387;
*aligned = 0xFEF8F387;
*aligned = 0xFEF8F387;
*aligned = 0xFEF8F387;
}
t3 = get_time();
uint64_t aligned_time = t3.val - t2.val;
ccprintf("Aligned took %" PRId64 "us, which is %" PRId64
"ns per iteration.\n",
aligned_time,
(1000 * aligned_time) / (iteration * unrollcount));
ccprintf("Unaligned write is %" PRId64 "%% slower that aligned.\n",
(100 * unaligned_time) / aligned_time - 100);
return EC_SUCCESS;
}
void run_test(int, const char **)
{
test_reset();
RUN_TEST(benchmark_unaligned_access);
test_print_result();
}