Merge branch 'master' into readwrite
This commit is contained in:
commit
a457b0fc40
10 changed files with 417 additions and 55 deletions
|
@ -28,7 +28,7 @@
|
|||
|
||||
#include "tests.h"
|
||||
|
||||
#ifdef START_KERNEL_JACOBI
|
||||
#if (defined(START_KERNEL_JACOBI) || defined(START_CHIEFTEST)) && defined(CONFIG_ROCKCREEK)
|
||||
|
||||
#define MATRIX_SIZE 256
|
||||
#define MAXVALUE 1337
|
||||
|
@ -353,14 +353,17 @@ int jacobi(void* argv)
|
|||
* check the result
|
||||
* X[i] have to be 1
|
||||
*/
|
||||
int err=0;
|
||||
for(i=0; i<MATRIX_SIZE; i++) {
|
||||
double diff = X[i] - 1.0;
|
||||
|
||||
error = fabs(diff);
|
||||
if (max < error)
|
||||
max = error;
|
||||
if (error > 0.01)
|
||||
if (error > 0.01) {
|
||||
kprintf("Result is on position %d wrong (%d/10000 != 1.0, error %d/10000)\n", i, (int) (10000.0*X[i]), (int) (10000.0*error));
|
||||
err = 1;
|
||||
}
|
||||
}
|
||||
kprintf("maximal error is %d/10000\n", (int) (10000.0*max));
|
||||
|
||||
|
@ -368,7 +371,7 @@ int jacobi(void* argv)
|
|||
kprintf("number of iterations: %d\n", iterations);
|
||||
kprintf("Calculation time: %llu ms (%llu ticks)\n", (stop-start)/(1000ULL*get_cpu_frequency()), stop-start);
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
|
||||
/* See http://www.nwlab.net/art/netio/netio.html to get the netio tool */
|
||||
|
||||
#if defined(START_NETIO) && defined(CONFIG_LWIP)
|
||||
#if (defined(START_NETIO) || defined(START_CHIEFTEST)) && defined(CONFIG_LWIP)
|
||||
#ifdef CONFIG_ROCKCREEK
|
||||
#if USE_SOCKET_BYPASSING // for socket bypassing
|
||||
#include <lwip/opt.h>
|
||||
|
|
172
apps/tests.c
172
apps/tests.c
|
@ -46,7 +46,7 @@ int jacobi(void* arg);
|
|||
void echo_init(void);
|
||||
void netio_init(void);
|
||||
|
||||
#ifdef START_CONSUMER_PRODUCER
|
||||
#if defined(START_CONSUMER_PRODUCER) || defined(START_CHIEFTEST)
|
||||
static sem_t consuming, producing;
|
||||
static mailbox_int32_t mbox;
|
||||
static int val = 0;
|
||||
|
@ -89,9 +89,28 @@ static int producer(void* arg)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int producer_consumer(void)
|
||||
{
|
||||
tid_t id1, id2, ret;
|
||||
int result1, result2, result;
|
||||
|
||||
create_kernel_task(&id1, producer, NULL, NORMAL_PRIO);
|
||||
create_kernel_task(&id2, consumer, NULL, NORMAL_PRIO);
|
||||
|
||||
ret = wait(&result);
|
||||
if (ret == id1) result1 = result;
|
||||
else result2 = result;
|
||||
|
||||
ret = wait(&result);
|
||||
if (ret == id1) result1 = result;
|
||||
else result2 = result;
|
||||
|
||||
return result1 || result2;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(START_FOO) || defined(START_JOIN_TEST)
|
||||
#if defined(START_FOO) || defined(START_JOIN_TEST) || defined(START_CHIEFTEST)
|
||||
static int foo(void* arg)
|
||||
{
|
||||
int i;
|
||||
|
@ -108,7 +127,7 @@ static int foo(void* arg)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef START_MAIL_PING
|
||||
#if (defined(START_MAIL_PING) || defined(START_CHIEFTEST)) && defined(CONFIG_ROCKCREEK)
|
||||
static int mail_ping(void* arg) {
|
||||
int i;
|
||||
|
||||
|
@ -132,7 +151,7 @@ static int mail_noise(void*arg) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef START_SVM_TEST
|
||||
#if (defined(START_SVM_TEST) || defined(START_CHIEFTEST)) && defined(CONFIG_ROCKCREEK)
|
||||
|
||||
/* N has to be multiple of UEs */
|
||||
|
||||
|
@ -173,6 +192,8 @@ static int svm_test(void *arg)
|
|||
if (!my_ue) {
|
||||
// allocate and initialize SVM region
|
||||
A[0] = (int*) kmalloc(3*N*N*sizeof(int));
|
||||
if (!A[0])
|
||||
return 1; // Let the others hang in the barrier. People will notice that things went wrong.
|
||||
memset((void*) A[0], 0x00, 3*N*N*sizeof(int));
|
||||
|
||||
// initialize matrices
|
||||
|
@ -188,7 +209,7 @@ static int svm_test(void *arg)
|
|||
GET_B(i,j) = i+j;
|
||||
}
|
||||
|
||||
kputs("Start sequentiell calculation...\n");
|
||||
kputs("Start sequential calculation...\n");
|
||||
|
||||
start = rdtsc();
|
||||
start = rdtsc();
|
||||
|
@ -203,7 +224,6 @@ static int svm_test(void *arg)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
end = rdtsc();
|
||||
|
||||
kprintf("Calculation time (seq): %llu ms (%llu ticks)\n", (end-start)/(1000ULL*get_cpu_frequency()), end-start);
|
||||
|
@ -222,6 +242,8 @@ static int svm_test(void *arg)
|
|||
kputs("Use Strong Release consistency!\n");
|
||||
|
||||
A[0] = (int*) svm_malloc(3*N*N*sizeof(int), svm_flags);
|
||||
if (!A[0])
|
||||
return 1;
|
||||
|
||||
#if 1
|
||||
if (!my_ue)
|
||||
|
@ -281,9 +303,8 @@ static int svm_test(void *arg)
|
|||
|
||||
kputs("Check results...\n");
|
||||
|
||||
uint32_t err = 0; // Be paranoid for a test case. return != 0 if calculation was not correct.
|
||||
if (!my_ue) {
|
||||
uint32_t err = 0;
|
||||
|
||||
svm_invalidate();
|
||||
for(i=0; (i<N) && (err < 32); i++) {
|
||||
for(j=0; (j<N) && (err < 32); j++) {
|
||||
|
@ -303,11 +324,11 @@ static int svm_test(void *arg)
|
|||
|
||||
svm_statistics();
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef START_SVM_BENCH
|
||||
#if (defined(START_SVM_BENCH) || defined(START_CHIEFTEST)) && defined(CONFIG_ROCKCREEK)
|
||||
static int svm_bench(void *arg)
|
||||
{
|
||||
volatile uint32_t* array = NULL;
|
||||
|
@ -328,6 +349,8 @@ static int svm_bench(void *arg)
|
|||
start = rdtsc();
|
||||
start = rdtsc();
|
||||
array = (volatile uint32_t*) svm_malloc(size, svm_flags);
|
||||
if (!array)
|
||||
return -1;
|
||||
end = rdtsc();
|
||||
|
||||
if (BUILTIN_EXPECT(!array, 0)) {
|
||||
|
@ -340,6 +363,7 @@ static int svm_bench(void *arg)
|
|||
svm_barrier(svm_flags);
|
||||
if (!RCCE_IAM) {
|
||||
start = rdtsc();
|
||||
// The pages are created by touching them for the first time.
|
||||
for(i=0; i<size/sizeof(uint32_t); i+=PAGE_SIZE/sizeof(uint32_t))
|
||||
array[i] = 0;
|
||||
end = rdtsc();
|
||||
|
@ -350,6 +374,9 @@ static int svm_bench(void *arg)
|
|||
svm_barrier(svm_flags);
|
||||
if (RCCE_IAM) {
|
||||
start = rdtsc();
|
||||
// Touching these pages from another core means moving them
|
||||
// to another owner as well as mapping them in the other core's
|
||||
// memory space.
|
||||
for(i=0; i<size/sizeof(uint32_t); i+=PAGE_SIZE/sizeof(uint32_t))
|
||||
array[i] = 1;
|
||||
end = rdtsc();
|
||||
|
@ -360,6 +387,8 @@ static int svm_bench(void *arg)
|
|||
svm_barrier(svm_flags);
|
||||
if (!RCCE_IAM) {
|
||||
start = rdtsc();
|
||||
// Touching the pages from the first core again only involves
|
||||
// moving the pages without the need to map them again.
|
||||
for(i=0; i<size/sizeof(uint32_t); i+=PAGE_SIZE/sizeof(uint32_t))
|
||||
array[i] = 0;
|
||||
end = rdtsc();
|
||||
|
@ -380,9 +409,21 @@ static int svm_bench(void *arg)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int testcase_svm_bench(void)
|
||||
{
|
||||
if (RCCE_IAM > 1) {
|
||||
int i;
|
||||
for (i=0; i < 6; i++)
|
||||
// Need as many barriers for the other cores as they occur in the benchmark.
|
||||
svm_barrier(SVM_TYPE);
|
||||
return 0;
|
||||
}
|
||||
return svm_bench(NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef START_JOIN_TEST
|
||||
#if defined(START_JOIN_TEST) || defined(START_CHIEFTEST)
|
||||
static int join_test(void* arg)
|
||||
{
|
||||
tid_t id, ret;
|
||||
|
@ -397,7 +438,7 @@ static int join_test(void* arg)
|
|||
|
||||
kprintf("Child %u finished: result = %d\n", id, result);
|
||||
|
||||
return 0;
|
||||
return result != 42;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -453,6 +494,8 @@ static int measure_ctx_switch(void* arg)
|
|||
for (i=0; i < REPS && stop == 0; i++) {
|
||||
while(id == sid && stop == 0) {
|
||||
t2 = rdtsc();
|
||||
// Calling rdtsc that often it is better
|
||||
// to serialize the calls in the pipeline.
|
||||
cpuid(0,&a,&b,&c,&d);
|
||||
}
|
||||
|
||||
|
@ -489,6 +532,99 @@ next_try:
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef START_CHIEFTEST
|
||||
|
||||
struct testcase_t {
|
||||
tid_t tid;
|
||||
int retval;
|
||||
char* userspace_argv[10];
|
||||
entry_point_t kernelspace_ep;
|
||||
char* testcase_name;
|
||||
};
|
||||
|
||||
#define USERSPACE_TC(execpath, name) {0, 0, {execpath, NULL}, NULL, name}
|
||||
#define KERNELSPACE_TC(execpointer, name) {0, 0, {NULL}, execpointer, name}
|
||||
|
||||
struct testcase_t testcases[] = {
|
||||
USERSPACE_TC("/bin/jacobi", "Jacobi serial user space app"),
|
||||
USERSPACE_TC("/bin/tests", "Tests user space app"),
|
||||
USERSPACE_TC("/bin/hello", "Hello userspace app"),
|
||||
KERNELSPACE_TC(producer_consumer, "Producer consumer kernel space test"),
|
||||
KERNELSPACE_TC(join_test, "Join kernel space test"),
|
||||
#ifdef CONFIG_ROCKCREEK
|
||||
KERNELSPACE_TC(svm_test, "SVM Test kernel space test"),
|
||||
KERNELSPACE_TC(testcase_svm_bench, "SVM Bench kernel space test"),
|
||||
KERNELSPACE_TC(mail_ping, "Mail Ping kernel space test"),
|
||||
// KERNELSPACE_TC(jacobi, "Jacobi kernel space test"),
|
||||
KERNELSPACE_TC(netio_init, "NetIO kernel space test")
|
||||
#endif
|
||||
};
|
||||
|
||||
static int chiefmastertest(void)
|
||||
{
|
||||
int tests = sizeof(testcases) / sizeof(struct testcase_t);
|
||||
int i;
|
||||
int result;
|
||||
tid_t id, ret;
|
||||
struct testcase_t* current;
|
||||
|
||||
kprintf("Starting chief master test: %d test cases.\n", tests);
|
||||
|
||||
for (i = 0; i < tests; i++) {
|
||||
current = &testcases[i];
|
||||
|
||||
#ifdef CONFIG_ROCKCREEK
|
||||
RCCE_barrier(&RCCE_COMM_WORLD);
|
||||
#endif
|
||||
kprintf("Starting testcase: %s\n", current->testcase_name);
|
||||
|
||||
if (current->kernelspace_ep == NULL &&
|
||||
current->userspace_argv[0] != NULL) {
|
||||
create_user_task(¤t->tid, current->userspace_argv[0],
|
||||
current->userspace_argv);
|
||||
} else if (current->kernelspace_ep != NULL &&
|
||||
current->userspace_argv[0] == NULL) {
|
||||
create_kernel_task(¤t->tid, current->kernelspace_ep,
|
||||
NULL, NORMAL_PRIO);
|
||||
} else {
|
||||
kprintf("Invalid test case struct #%d!\n", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
do {
|
||||
ret = wait(&result);
|
||||
} while(ret != current->tid);
|
||||
|
||||
kprintf("Testcase %s returned %d %s\n", current->testcase_name, result, result ? ":(" : ":)");
|
||||
|
||||
current->retval = result;
|
||||
}
|
||||
|
||||
|
||||
kprintf("======================================================\n");
|
||||
kprintf("Master Chief test case results:\n");
|
||||
for (i = 0; i < tests; i++) {
|
||||
current = &testcases[i];
|
||||
|
||||
kprintf("%s: ", current->testcase_name);
|
||||
if (current->retval) {
|
||||
pushfg(COL_RED);
|
||||
kprintf("Bad :(");
|
||||
} else {
|
||||
pushfg(COL_GREEN);
|
||||
kprintf("Pass :)");
|
||||
}
|
||||
popfg();
|
||||
popbg();
|
||||
kprintf("\n");
|
||||
}
|
||||
kprintf("======================================================\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // START_CHIEFTEST
|
||||
|
||||
int test_init(void)
|
||||
{
|
||||
#ifdef START_HELLO
|
||||
|
@ -505,19 +641,23 @@ int test_init(void)
|
|||
char* client_argv[] = {"/bin/client", "192.168.0.1", "6789", NULL};
|
||||
#endif
|
||||
|
||||
#ifdef START_CHIEFTEST
|
||||
create_kernel_task(NULL, chiefmastertest, NULL, NORMAL_PRIO);
|
||||
#endif
|
||||
|
||||
#ifdef START_ECHO
|
||||
echo_init();
|
||||
#endif
|
||||
#ifdef START_NETIO
|
||||
netio_init();
|
||||
#endif
|
||||
#ifdef START_CONSUMER_PRODUCER
|
||||
#if defined(START_CONSUMER_PRODUCER) || defined(START_CHIEFTEST)
|
||||
sem_init(&producing, 1);
|
||||
sem_init(&consuming, 0);
|
||||
mailbox_int32_init(&mbox);
|
||||
|
||||
create_kernel_task(NULL, producer, NULL, NORMAL_PRIO);
|
||||
create_kernel_task(NULL, consumer, NULL, NORMAL_PRIO);
|
||||
#endif
|
||||
#ifdef START_CONSUMER_PRODUCER
|
||||
create_kernel_task(NULL, producer_consumer, NULL, NORMAL_PRIO);
|
||||
#endif
|
||||
#ifdef START_MEASURE_CTX_SWITCH
|
||||
create_kernel_task(NULL, measure_ctx_switch, (int)0, NORMAL_PRIO);
|
||||
|
|
|
@ -47,6 +47,8 @@
|
|||
#define START_TESTS
|
||||
//#define START_JACOBI
|
||||
|
||||
//#define START_CHIEFTEST
|
||||
|
||||
// does our demos require GFX support?
|
||||
//#define CONFIG_GFX
|
||||
|
||||
|
|
161
documentation/text/benchmarks.dox
Normal file
161
documentation/text/benchmarks.dox
Normal file
|
@ -0,0 +1,161 @@
|
|||
/**
|
||||
* @file benchmarks.dox
|
||||
* @page benchmarks Benchmarks and Example Applications
|
||||
*
|
||||
*
|
||||
* @section toc Table of Contents
|
||||
* - @ref scc_ks
|
||||
* - @ref general_ks
|
||||
* - @ref general_us
|
||||
*
|
||||
* @section kernelspace Kernel Space Applications/Benchmarks
|
||||
* Located in: `apps/`
|
||||
*
|
||||
* You can activate/deactivate the start of these applications after booting MetalSVM
|
||||
* using the \c \#define flags in `apps/tests.h`.
|
||||
* The configuration looks like (Just remove the comment prefix from the applications
|
||||
* you would like to start):
|
||||
* \code
|
||||
...
|
||||
//#define START_SVM_TEST
|
||||
#define START_SVM_BENCH
|
||||
//#define START_MAIL_PING
|
||||
#define START_MAIL_NOISE
|
||||
//#define START_KERNEL_LAPLACE
|
||||
//#define START_KERNEL_JACOBI
|
||||
...
|
||||
* \endcode
|
||||
*
|
||||
* There are SCC-specific as well as generic kernel space applications and benchmarks.
|
||||
* Most of these applications are located in `apps/tests.c`, unless otherwise noted:
|
||||
*
|
||||
* @subsection scc_ks SCC-specific
|
||||
*
|
||||
* - __SVM_TEST__: This application creates three matrices A, B and C in
|
||||
* shared memory fields and calculates C = A * B.
|
||||
*
|
||||
* After calculation, it checks the result for correctness, compares execution
|
||||
* time between serial calculation and shared memory parallelization and prints
|
||||
* statistics about the different cores' access to shared pages.
|
||||
*
|
||||
* You can configure different SVM release consistency models: Set the
|
||||
* \#define-constant `SVM_TYPE` to either `SVM_LAZYRELEASE` or `SVM_STRONG`.
|
||||
* The `GET_B(i, j)` macro can be configured to transpose the matrix rows and
|
||||
* columns.
|
||||
*
|
||||
* - __SVM_BENCH__: A benchmark for two executing cores.
|
||||
*
|
||||
* At first some shared memory pages are allocated. The benchmark measures the
|
||||
* time the SVM implementation needs for creating and moving these pages between
|
||||
* the cores.
|
||||
*
|
||||
* You can configure different SVM release consistency models: Set the
|
||||
* \#define-constant `SVM_TYPE` to either `SVM_LAZYRELEASE` or `SVM_STRONG`.
|
||||
*
|
||||
* - __MAIL_PING__: MetalSVM provides a mailbox system using the iRCCE library as
|
||||
* a foundation for communication between the SCC-cores. In this benchmark the
|
||||
* latency of intercore-pings is measured: This involves sending a a PING-message,
|
||||
* an intercore-interrupt, and waiting for the answer.
|
||||
*
|
||||
* - __MAIL_NOISE__: A high number of messages is sent from all cores to all cores to
|
||||
* generate noise on the on-die mesh.
|
||||
*
|
||||
* Latency is measured, but this noise can also be used to check performance of
|
||||
* other applications under influence of noise.
|
||||
*
|
||||
* - __KERNEL_LAPLACE__: This application iterates over a shared memory field with
|
||||
* the laplace differential equation solver. Execution time will be measured.
|
||||
*
|
||||
* You can configure different SVM release consistency models: Set the
|
||||
* \#define-constant `SVM_TYPE` to either `SVM_LAZYRELEASE` or `SVM_STRONG`.
|
||||
*
|
||||
* Location: `apps/laplace.c`
|
||||
*
|
||||
* - __KERNEL_JACOBI__: A shared memory implementation of the jacobi matrix equation
|
||||
* solver. This is an interesting SVM example application, because besides
|
||||
* `svm_barrier()`, it also uses `svm_flush()` and `svm_invalidate()`.
|
||||
*
|
||||
* You can configure different SVM release consistency models: Set the
|
||||
* \#define-constant `SVM_TYPE` to either `SVM_LAZYRELEASE` or `SVM_STRONG`.
|
||||
*
|
||||
* Location: `apps/jacobi.c`
|
||||
*
|
||||
* - __ECHO__: Starts a new system thread providing an echo service over network
|
||||
* listening on port 7.
|
||||
*
|
||||
* Location: `apps/echo.c`
|
||||
*
|
||||
* - **NETIO**: Measures the network throughput between two cores on the on-die mesh
|
||||
* for different packet sizes.
|
||||
*
|
||||
* This benchmark consists of 2 kernel space tasks.
|
||||
*
|
||||
* Task 1 is the TCP server listening on port 18767. It will be started on RCCE
|
||||
* rank 2. As a reaction to commands from a client it will send/receive data and
|
||||
* measure the bandwidth of the transmission.
|
||||
*
|
||||
* Task 2 is the TCP client started on RCCE rank 0. It connects to the server task
|
||||
* and sends commands to send/receive data, doing the same performance measurements
|
||||
* as the server task.
|
||||
*
|
||||
* If the kernel is not configured for the SCC (`CONFIG_ROCKCREEK`), only the
|
||||
* server task will be started. The client has to be started manually from elsewhere
|
||||
* in this case.
|
||||
*
|
||||
* A possibility to improve the performance is bypassing the socket interface.
|
||||
* To do this, activate the \#define constant `USE_SOCKET_BYPASSING` in the same file
|
||||
* to a value != 0.
|
||||
*
|
||||
* Location: `apps/netio.c`
|
||||
*
|
||||
* @subsection general_ks Generic
|
||||
*
|
||||
* - __CONSUMER_PRODUCER__: A typical producer-consumer scenario testing the
|
||||
* semaphore mechanism. After some cycles of producing and consuming, messages are
|
||||
* sent over the mailbox interface.
|
||||
*
|
||||
* - __FOO__: A primitive kernel task example printing 5 kernel messages every second.
|
||||
* Can be started multiple times to test the scheduler.
|
||||
*
|
||||
* - __JOIN_TEST__: A task starts a new child task executing the `foo`-example and
|
||||
* and quits after the child task has executed using the `wait()` function.
|
||||
*
|
||||
* - __PI__: Serial calculation of pi.
|
||||
*
|
||||
* - __MEASURE_CTX_SWITCH__: Measures the pure overhead ticks of a context switch
|
||||
* between 2 kernel space tasks.
|
||||
*
|
||||
* Both tasks continuously write the current TSC count to a shared variable until
|
||||
* they are preempted and print the tick count the last context switch took.
|
||||
*
|
||||
*
|
||||
* @section general_us Generic User Space Applications
|
||||
*
|
||||
* Located in: `newlib/examples/`
|
||||
*
|
||||
* - __MMNIF_TEST__: Starts a Server task on the first RCCE rank and
|
||||
* a client task on every other rank. The clients request an example string
|
||||
* to print it afterwards, while the server keeps responding with this string.
|
||||
*
|
||||
*
|
||||
* - __hello__: Prints all environment variables and command line parameters.
|
||||
* Opens a test file, writes an example string to it, reads the same string
|
||||
* out again and afterwards prints the first directory entry of the `/bin`
|
||||
* directory.
|
||||
*
|
||||
* - __jacobi__: A usual jacobi matrix solver application. Measures its execution time.
|
||||
*
|
||||
* - __mshell__: The M(etalsvm)shell provides basic commands to navigate through
|
||||
* the file system, print out files and start applications.
|
||||
*
|
||||
* - __rlogind__: Started after boot by default, the rlogin daemon listens to port 4711.
|
||||
*
|
||||
* It pipes stdin and stdout over network, making shell access over telnet possible.
|
||||
*
|
||||
* - __tests__: Initiates a fork, where the child task starts an instance of the
|
||||
* `hello` application with custom environment variables and command line parameters.
|
||||
* The parent process waits for the child process to exit.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
|
@ -16,11 +16,10 @@
|
|||
*
|
||||
* \verbatim$ git clone git://git.lfbs.rwth-aachen.de/metalsvm.git \endverbatim
|
||||
*
|
||||
* If you are asked for a password you are not authorized to clone the repository. In this case you will need to get your public SSH key authorized.
|
||||
*
|
||||
* @section compiling Compiling MetalSVM
|
||||
*
|
||||
* To compile MetalSVM, you will need a proper Makefile and configuration. To use the example files, just do the following:
|
||||
* To compile MetalSVM, you will need a proper Makefile and configuration.
|
||||
* To use the example files, just do the following:
|
||||
*
|
||||
* \verbatim
|
||||
$ cd MetalSVM
|
||||
|
@ -28,8 +27,10 @@ $ cp Makefile.example Makefile
|
|||
$ (cd include/metalsvm; cp config.h.example config.h) \endverbatim
|
||||
*
|
||||
* The standard configuration works on usual PC hardware configurations as well as in emulators.
|
||||
* There are also preconfigured example configs for the Intel SCC: `Makefile.scc` and `config.h.scc`.
|
||||
*
|
||||
* Compiler settings can be edited in the Makefile, while the kernel configuration can be found in the just copied configuration file.
|
||||
* Compiler settings can be edited in the Makefile, while the kernel configuration can be
|
||||
* found in the configuration header file.
|
||||
*
|
||||
* @section runqemu Running MetalSVM in Qemu
|
||||
*
|
||||
|
@ -41,19 +42,12 @@ $ (cd include/metalsvm; cp config.h.example config.h) \endverbatim
|
|||
*
|
||||
* @section runscc Running MetalSVM on the Intel SCC
|
||||
*
|
||||
* -# Intel recommends to use their cross-compiler for generating code which is guaranteed to be SCC-compatible. Just set the environment variables with the following command:
|
||||
* \verbatim$ . /opt/compilerSetupFiles/crosscompile.sh \endverbatim
|
||||
* -# The Makefile needs to be adapted to actually use the cross compiler.
|
||||
* Just uncomment two lines like seen here:
|
||||
* \code
|
||||
# Set your own cross compiler tool chain prefix here
|
||||
CROSSCOMPREFIX=
|
||||
|
||||
# Uncomment both lines if compiling for the SCC!
|
||||
CROSSCOMPREFIX=i386-unknown-linux-gnu-
|
||||
STACKPROT=\endcode
|
||||
* -# Another important change in the Makefile is disabling the "-fno-stack-protector" option. It occurs several times.
|
||||
* -# The SCC requires a special configuration for the MetalSVM kernel:
|
||||
* -# Although Intel provides a special older GCC version for compiling code for the Intel SCC,
|
||||
* the MetalSVM project switched to the current standard GCC. You don't need to source
|
||||
* the cross compiler script which might be installed on your MCPC.
|
||||
* -# An important change in the Makefile is disabling the "-fno-stack-protector" option. It occurs several times. This has already been done for you if you use `Makefile.scc`.
|
||||
* -# The SCC requires a special configuration for the MetalSVM kernel (Already been done
|
||||
* if you use `config.h.scc`):
|
||||
* \code
|
||||
//#define CONFIG_PCI
|
||||
//#define CONFIG_VGA
|
||||
|
@ -78,6 +72,7 @@ STACKPROT=\endcode
|
|||
* \verbatim
|
||||
$ cd tools
|
||||
$ make SCC \endverbatim
|
||||
*
|
||||
* -# The \c obj directory was just created, containing the MetalSVM kernel image. It can be loaded into the SCC's memory using \verbatim$ sccBoot -g obj \endverbatim
|
||||
* -# The default configuration lets MetalSVM run only on core 0. Its reset pin needs to be released:
|
||||
* \verbatim$ sccReset -r 0x00 \endverbatim
|
||||
|
@ -90,9 +85,10 @@ $ make SCC \endverbatim
|
|||
* -# Build the kernel like described above (items 1-7) and change to the \c tools directory.
|
||||
* -# Now the file \c metalsvm.mt can be edited, depending on how many cores you want MetalSVM running.
|
||||
* Just remove the cores which shall be unaffected. Having a slim \c metalsvm.tm accelerates the build procedure.
|
||||
* -# The final image must be generated then with \code$ make SCC\endcode
|
||||
* -# The final image must be generated then with \code$ make SCC CORENUM=48\endcode
|
||||
* where `CORENUM` is set to the actual number of cores which shall work together later.
|
||||
* -# A directory \c obj was created, containing the final MetalSVM Image. This image can now be loaded with the following command: \code$ sccBoot -g obj\endcode
|
||||
* -# Everything has been placed in the cores' memory. To release the reset pins of the corresponding cores, type \code$ sccReset -r 0x00 0x01\endcode
|
||||
* -# Everything has been placed in the cores' memory. To release the reset pins of the corresponding cores, type \code$ sccReset -r 0 1 2 3 ...\endcode
|
||||
*
|
||||
* @section msvmuart Enabling UART support
|
||||
*
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
/**
|
||||
* @file config.dox
|
||||
* @page config The MetalSVM feature configuration file
|
||||
* @page config MetalSVM feature configuration files
|
||||
*
|
||||
* @section conf MetalSVM's configuration file
|
||||
* @section main_config MetalSVM's main configuration file
|
||||
*
|
||||
* MetalSVM's configuration parameters and some features can be configured/activated in the central configuration file located at \c include/metalsvm/config.h.
|
||||
* MetalSVM's configuration parameters and some features can be configured/activated
|
||||
* in the central configuration file located at \c include/metalsvm/config.h.
|
||||
*
|
||||
* The \c config.h is a usual C-header file and the configuration items are usual C preprocessor-definitions like the following:
|
||||
* The `config.h` is a usual C header file and the configuration items are usual
|
||||
* C preprocessor-definitions like the following:
|
||||
* \code
|
||||
#define CONFIGURATION_PARAMETER 123value /* A parameter with a value */
|
||||
#define FEATURE_A /* An activated feature */
|
||||
|
@ -14,5 +16,53 @@
|
|||
*
|
||||
* Just like the example suggests, features are deactivated by commenting them out.
|
||||
*
|
||||
* If you boot MetalSVM on the Intel SCC, you need to \b deactivate `CONFIG_PCI`,
|
||||
* `CONFIG_VGA`, `CONFIG_KEYBOARD`, and `CONFIG_MULTIBOOT` and
|
||||
* \b activate `CONFIG_ROCKCREEK`. Set `CACHE_LINE` to 32.\n
|
||||
* Activate `CONFIG_UART` if you are going to use software-UART and deactivate it if
|
||||
* not, to avoid unnecessary traffic.
|
||||
*
|
||||
* @section lwip_config LwIP configuration flags
|
||||
*
|
||||
* The networking subsystem, based on LwIP, can of course be influenced by various
|
||||
* feature flags.
|
||||
*
|
||||
* MetalSVM overrides various standard settings in `lwip/src/include/lwipopts.h`.
|
||||
*
|
||||
* If you chose `CONFIG_ROCKCREEK`, this leads to deactivation of `LWIP_DHCP`.
|
||||
*
|
||||
* If you chose `CONFIG_TICKLESS`, `NO_SYS` will be activated and the following
|
||||
* are deactivated: `LWIP_SOCKET`, `LWIP_NETCON`, `LWIP_NETIF_API`.
|
||||
*
|
||||
* Another interesting feature is `LWIP_CHECKSUM_ON_COPY`. Deactivating it leads
|
||||
* to higher network throughput for on-die communication.
|
||||
*
|
||||
* See LwIP documentation for more specific information about the individual effects of
|
||||
* manipulating the LwIP configuration flags/values.
|
||||
*
|
||||
* @section mmnif_config MMNIF configuration flags
|
||||
* Several flags in the file `drivers/net/mmnif.c` file influence the memory
|
||||
* mapped network interface's performance:
|
||||
*
|
||||
* - `USE_CACHE`: activates the cache for the memory mapped buffer region.
|
||||
* This improves the performance.
|
||||
* - `USE_MPB`: If activated, the buffer will be mapped onto the SCC's special MPB,
|
||||
* which improves the performance drastically.
|
||||
*
|
||||
* @section svm_config SVM configuration flags
|
||||
*
|
||||
* Although the choice between different shared memory release consistency models
|
||||
* is configured in the application code, there are 2 flags which influence the SVM
|
||||
* implementation. These are located in `arch/x86/mm/svm.c`:
|
||||
*
|
||||
* - `USE_PERFCOUNTERS`: Performance counters will help evaluating the performance
|
||||
* of the SVM implementation within the kernel. Deactivate to omit overhead.
|
||||
*
|
||||
* - `USE_RESP_MAIL`: Whenever a core requests access to a page it is not the owner
|
||||
* of, it sends an interrupt to the owner. The requesting core will then wait for the mail
|
||||
* indicating that it has become the new owner of the particular page, spinning on its mailbox.
|
||||
* When `USE_RESP_MAIL` is activated, other interrupts will be deactivated until the response
|
||||
* has arrived.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -108,7 +108,7 @@ static int foo(void* arg)
|
|||
* \c make in the project directory.
|
||||
*
|
||||
* The initrd building scripts include every file within the \c newlib/examples/
|
||||
* directory which is marked as \b execuable. Do not forget this if you use your
|
||||
* directory which is marked as \b executable. Do not forget this if you use your
|
||||
* own build scripts!
|
||||
*
|
||||
* After providing your own executable for the system within the initial ramdisk,
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#define NR_OPEN 10
|
||||
#define FS_INIT { [0 ... NR_OPEN-1] = {NULL, 0, 0} }
|
||||
|
||||
#define TESTSTR "hello in new file '/bin/test.txt'"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int i, testfile;
|
||||
|
@ -43,25 +45,31 @@ int main(int argc, char** argv)
|
|||
|
||||
teststr = malloc(sizeof(char)*100);
|
||||
if (!teststr)
|
||||
return EFAULT;
|
||||
exit(1);
|
||||
|
||||
testfile = open("/bin/test.txt", O_CREAT | O_EXCL, "wr");
|
||||
if (testfile < 1)
|
||||
printf("error");
|
||||
write(testfile, "hello in new file '/bin/test.txt'", 34);
|
||||
if (testfile < 1) {
|
||||
printf("error: Was not able to open /bin/test.txt\n");
|
||||
exit(1);
|
||||
}
|
||||
write(testfile, TESTSTR, 34);
|
||||
lseek(testfile, 0, SEEK_SET);
|
||||
read(testfile, teststr, 100);
|
||||
close(testfile);
|
||||
|
||||
printf("read from new file: %s\n", teststr);
|
||||
|
||||
if (strcmp(teststr, TESTSTR))
|
||||
exit(1);
|
||||
|
||||
testdir = opendir("/bin/");
|
||||
if (testdir < 1)
|
||||
printf("error");
|
||||
if (testdir < 1) {
|
||||
printf("error: Was not able to open /bin directory");
|
||||
exit(1);
|
||||
}
|
||||
testdirent = readdir(testdir);
|
||||
printf("1. Dirent: %s", testdirent->d_name);
|
||||
closedir(testdir);
|
||||
|
||||
|
||||
printf("read from new file: %s\n", teststr);
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
|
|
@ -178,8 +178,10 @@ int main(int argc, char **argv)
|
|||
|
||||
if (max < error)
|
||||
max = error;
|
||||
if (error > 0.01f)
|
||||
printf("Result is on position %d wrong (%f != 1.0)\n", i, X[i]);
|
||||
if (error > 0.01f) {
|
||||
printf("Result is on position %d wrong (%f != 1.0)\n", i, X[i]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
printf("maximal error is %f\n", max);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue