mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-31 08:25:38 +00:00
test/cache: refine test pattern
- run multiple access patterns (touch words, touch lines, memcpy) - add make file for linux genodelabs/genode#4454
This commit is contained in:
parent
5a0e22eb98
commit
052c33fc8c
55
repos/os/src/test/cache/common.h
vendored
Normal file
55
repos/os/src/test/cache/common.h
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* \brief Test defintions common for Genode and Linux
|
||||
* \author Johannes Schlatow
|
||||
* \date 2022-03-07
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _SRC__TEST__CACHE__COMMON_H_
|
||||
#define _SRC__TEST__CACHE__COMMON_H_
|
||||
|
||||
template <typename TEST>
|
||||
unsigned long timed_test(void * src, void * dst, size_t sz, unsigned iterations, TEST && func)
|
||||
{
|
||||
Time s { };
|
||||
|
||||
for (; iterations; iterations--)
|
||||
func(src, dst, sz);
|
||||
|
||||
{
|
||||
Time e { } ;
|
||||
Duration d = Time::duration(s, e);
|
||||
return d.value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void touch_words(void * src, void *, size_t size)
|
||||
{
|
||||
unsigned * data = reinterpret_cast<unsigned*>(src);
|
||||
for (size = size/sizeof(unsigned); size; size--)
|
||||
data[size]++;
|
||||
}
|
||||
|
||||
|
||||
template<size_t START_SZ_KB, size_t END_SZ_KB, typename TEST>
|
||||
void sweep_test(void * src, void * dst, unsigned iterations, TEST && func)
|
||||
{
|
||||
size_t size = START_SZ_KB;
|
||||
while (size <= END_SZ_KB)
|
||||
{
|
||||
func(src, dst, size*1024, iterations);
|
||||
|
||||
size = size << 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* _SRC__TEST__CACHE__COMMON_H_ */
|
38
repos/os/src/test/cache/genode_time.h
vendored
Normal file
38
repos/os/src/test/cache/genode_time.h
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* \brief Time-taking defintions for Genode test cases
|
||||
* \author Johannes Schlatow
|
||||
* \date 2022-03-07
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _SRC__TEST__CACHE__GENODE_TIME_H_
|
||||
#define _SRC__TEST__CACHE__GENODE_TIME_H_
|
||||
|
||||
#include <trace/timestamp.h>
|
||||
|
||||
using namespace Genode::Trace;
|
||||
using namespace Genode;
|
||||
|
||||
struct Duration { unsigned long value; };
|
||||
|
||||
struct Time
|
||||
{
|
||||
Timestamp _ts { timestamp() };
|
||||
|
||||
static Duration duration(Time t1, Time t2)
|
||||
{
|
||||
Timestamp diff = t2._ts - t1._ts;
|
||||
if (t2._ts < t1._ts) diff--;
|
||||
|
||||
return Duration { (unsigned long)diff };
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _SRC__TEST__CACHE__GENODE_TIME_H_ */
|
13
repos/os/src/test/cache/linux/Makefile
vendored
Normal file
13
repos/os/src/test/cache/linux/Makefile
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
INC_DIR = $(PWD)/..
|
||||
|
||||
ifneq (,$(findstring arm-,$(shell gcc -dumpmachine)))
|
||||
CC_MARCH = -marm
|
||||
else
|
||||
CC_MARCH =
|
||||
endif
|
||||
|
||||
cache: main.cc $(INC_DIR)/common.h
|
||||
g++ -I$(INC_DIR) $(CC_MARCH) -O2 -Wall -Wextra -Weffc++ -std=gnu++11 $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f *~ cache
|
60
repos/os/src/test/cache/linux/main.cc
vendored
Normal file
60
repos/os/src/test/cache/linux/main.cc
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <cstdio>
|
||||
|
||||
struct Duration { unsigned long value; };
|
||||
|
||||
struct Time
|
||||
{
|
||||
timespec _timespec { 0, 0 };
|
||||
|
||||
Time()
|
||||
{
|
||||
clock_gettime(CLOCK_REALTIME, &_timespec);
|
||||
}
|
||||
|
||||
Time(timespec timespec) : _timespec(timespec) { }
|
||||
|
||||
static Duration duration(Time t1, Time t2)
|
||||
{
|
||||
auto usecs = [&] (timespec ts) {
|
||||
return 1000UL*1000UL*((unsigned long)ts.tv_sec % 1000UL)
|
||||
+ (unsigned long)ts.tv_nsec/1000UL; };
|
||||
|
||||
return Duration { usecs(t2._timespec) - usecs(t1._timespec) };
|
||||
}
|
||||
};
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
void triplet_test(void * src, void * dst, size_t size, unsigned iterations)
|
||||
{
|
||||
size_t size_kb = size / 1024;
|
||||
|
||||
unsigned long res1 = timed_test(src, nullptr, size, iterations, touch_words);
|
||||
unsigned long res2 = timed_test(src, src, size, iterations, memcpy);
|
||||
unsigned long res3 = timed_test(src, dst, size, iterations, memcpy);
|
||||
|
||||
printf("%luKB (nsec/KB): %lu | %lu | %lu\n", size_kb,
|
||||
1000*res1 / size_kb / iterations,
|
||||
1000*res2 / size_kb / iterations,
|
||||
1000*res3 / size_kb / iterations);
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
enum { MAX_KB = 4*1024 };
|
||||
|
||||
char * buf1 = new char[MAX_KB*1024];
|
||||
char * buf2 = new char[MAX_KB*1024];
|
||||
|
||||
memset(buf1, 0, MAX_KB*1024);
|
||||
memset(buf2, 0, MAX_KB*1024);
|
||||
|
||||
sweep_test<8, MAX_KB>(buf1, buf2, 100, triplet_test);
|
||||
|
||||
delete[] buf1;
|
||||
delete[] buf2;
|
||||
}
|
81
repos/os/src/test/cache/main.cc
vendored
81
repos/os/src/test/cache/main.cc
vendored
@ -15,56 +15,24 @@
|
||||
#include <base/log.h>
|
||||
#include <base/component.h>
|
||||
#include <base/heap.h>
|
||||
#include <trace/timestamp.h>
|
||||
|
||||
using namespace Genode::Trace;
|
||||
#include "genode_time.h"
|
||||
#include "common.h"
|
||||
|
||||
class Test
|
||||
void triplet_test(void * src, void * dst, size_t size, unsigned iterations)
|
||||
{
|
||||
private:
|
||||
Genode::Heap &_alloc;
|
||||
Genode::size_t _size;
|
||||
size_t size_kb = size / 1024;
|
||||
|
||||
unsigned *_data { 0 };
|
||||
unsigned long res1 = timed_test(src, nullptr, size, iterations, touch_words);
|
||||
unsigned long res2 = timed_test(src, src, size, iterations, memcpy_cpu);
|
||||
unsigned long res3 = timed_test(src, dst, size, iterations, memcpy_cpu);
|
||||
|
||||
Timestamp ts_to_time(Timestamp start, Timestamp end)
|
||||
{
|
||||
Timestamp diff = end - start;
|
||||
if (end < start) diff--;
|
||||
log(size_kb, "KB (Cycles/KB): ",
|
||||
res1 / size_kb / iterations, " | ",
|
||||
res2 / size_kb / iterations, " | ",
|
||||
res3 / size_kb / iterations);
|
||||
}
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
Test(const Test &);
|
||||
void operator=(const Test&);
|
||||
|
||||
public:
|
||||
|
||||
Test(Genode::Heap &alloc, Genode::size_t size_bytes)
|
||||
: _alloc(alloc),
|
||||
_size(size_bytes/sizeof(unsigned))
|
||||
{
|
||||
_data = new (_alloc) unsigned[_size];
|
||||
}
|
||||
|
||||
~Test()
|
||||
{
|
||||
destroy(_alloc, _data);
|
||||
}
|
||||
|
||||
Timestamp read_write(unsigned iterations=100)
|
||||
{
|
||||
Timestamp start_ts = timestamp();
|
||||
|
||||
for (Genode::size_t i=0; i < iterations; i++) {
|
||||
for (Genode::size_t index=0; index < _size; index++) {
|
||||
_data[index]++;
|
||||
}
|
||||
}
|
||||
|
||||
return ts_to_time(start_ts, timestamp()) / iterations;
|
||||
}
|
||||
};
|
||||
|
||||
struct Main
|
||||
{
|
||||
@ -80,28 +48,23 @@ Main::Main(Genode::Env &env) : env(env)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
log("--- test-cache started ---");
|
||||
enum { MAX_KB = 4*1024 };
|
||||
|
||||
enum {
|
||||
START_SIZE = 8,
|
||||
END_SIZE = 1024 * 4,
|
||||
THRESHOLD_PERCENT = 10,
|
||||
};
|
||||
char * buf1 = new (heap) char[MAX_KB*1024];
|
||||
char * buf2 = new (heap) char[MAX_KB*1024];
|
||||
|
||||
size_t size = START_SIZE;
|
||||
while (size <= END_SIZE)
|
||||
{
|
||||
log("\n--- Running tests for size ", size, "KB ---");
|
||||
memset(buf1, 0, MAX_KB*1024);
|
||||
memset(buf2, 0, MAX_KB*1024);
|
||||
|
||||
Test test(heap, size*1024);
|
||||
log("Read/write: ", test.read_write() / size, " cycles on average per KB");
|
||||
log("--- test-cache started (touch words | touch lines | memcpy) ---");
|
||||
|
||||
size = size << 1;
|
||||
}
|
||||
sweep_test<8, MAX_KB>(buf1, buf2, 30, triplet_test);
|
||||
|
||||
log("--- test-cache done ---");
|
||||
|
||||
destroy(heap, buf1);
|
||||
destroy(heap, buf2);
|
||||
}
|
||||
|
||||
void Component::construct(Genode::Env &env) { static Main inst(env); }
|
||||
Genode::size_t Component::stack_size() { return 32*1024*sizeof(long); }
|
||||
|
||||
|
1
repos/os/src/test/cache/target.mk
vendored
1
repos/os/src/test/cache/target.mk
vendored
@ -1,3 +1,4 @@
|
||||
TARGET = test-cache
|
||||
SRC_CC = main.cc
|
||||
INC_DIR += $(PRG_DIR)
|
||||
LIBS = base
|
||||
|
Loading…
x
Reference in New Issue
Block a user