source: soft/giet_vm/sort/main.c @ 278

Last change on this file since 278 was 271, checked in by cfuguet, 10 years ago
  • Bugfix: The ISR_SWITCH index should be NB_PROCS_MAX + local_pid. This is because the first NB_PROCS_MAX indexes on the XICU in each cluster are used for the WAKEUP software interrupts.
  • Relocating the memcpy and memset functions into the giet_libs/stdlib.* files.
  • Modification of the sort application to used 8 threads instead of
    1. Modifying the mapping files to distribute the 8 threads on the available processors. (Ex. When using 4 processors, each one executes 2 threads)
  • Property svn:executable set to *
File size: 6.3 KB
RevLine 
[257]1///////////////////////////////////////////////////////////////////////////////
2// File :
3//     
4//      main.c
[256]5//
[257]6// Date :
7//     
8//      November 2013
[256]9//
[257]10// Author :
[256]11//
[257]12//      Cesar Fuguet Tortolero <cesar.fuguet-tortolero@lip6.fr>
13//
14// Description :
15//
16//      Sort application using the GIET-VM OS. This application uses the
17//      barrier routines to apply a sort algorithm in several stages.
18//
19//      Considerations :
20//
21//          - It supports up to 256 processors and the number of processors
22//            must be a power of 2.
23//
24//          - If there is only one TTY available, this application uses a spin
25//            lock to avoid several threads writting at the same time.
26//
27//          - This application must be executed on a cache coherent
28//            architecture. Otherwise some modifications must be applied
29//
30//          - The processors executing this application must have a contiguous
31//            processor id and the first processor must have id 0.
32//
33///////////////////////////////////////////////////////////////////////////////
[256]34
35#include "stdio.h"
36#include "hard_config.h"
37#include "barrier.h"
38
[257]39//////////////////////////////////////////////////////////////////////////
[271]40// The NTHREADS constant must be modified depending on the desired number of
[257]41// threads
42
[271]43#define NTHREADS        8
44#define ARRAY_LENGTH    (NTHREADS * 128)
45#define IPT             (ARRAY_LENGTH / NTHREADS) // ITEMS PER THREAD
[256]46
[257]47////////////////////////////////////////////////////////////////////////////////
48// Processors other than 0 display algorithm state
49// The processor 0 always displays some information so this does not affect him
50
[256]51#define VERBOSE         1
52
[257]53///////////////////////////////////////////////////////////////////////
54// Define printf according to verbosity option and number of available
55// TTY
56
[256]57#if (VERBOSE == 1)
[269]58#   define printf(...)     giet_tty_printf(__VA_ARGS__)
59#   define puts(...)       giet_tty_puts(__VA_ARGS__)
[257]60#else       // VERBOSE == 0
61#   define printf(...)
62#   define puts(...)
[256]63#endif
64
[269]65#define task0_printf(...) if(thread_id == 0) giet_tty_printf(__VA_ARGS__)
[257]66
[256]67#define exit    giet_exit
68#define procid  giet_procid
69#define rand    giet_rand
70
71int array0[ARRAY_LENGTH];
72int array1[ARRAY_LENGTH];
73
74volatile int init_ok = 0;
75
76void bubbleSort(
77        int * array,
78        unsigned int length,
79        unsigned int init_pos);
80
81void merge(
82        int * array,
83        int * result,
84        int length,
85        int init_pos_a,
86        int init_pos_b,
87        int init_pos_result);
88
[257]89///////////////////////////////////////////////////
90// This application support at most 256 processors
[271]91// Number of barriers = log2(NTHREADS)
[257]92
[256]93giet_barrier_t barrier[8];
94
95__attribute__ ((constructor)) void sort()
96{
[269]97    int thread_id = giet_thread_id();
98
[256]99    int * src_array;
100    int * dst_array;
101    int i;
102
[271]103    printf("[ Thread %d ] Initializing vector and barriers...\n\r", thread_id);
[256]104
[269]105    ///////////////////////////
106    // Barriers Initialization
[256]107
[271]108    for (i = 0; i < __builtin_ctz(NTHREADS); i++)
[256]109    {
[271]110        barrier_init(&barrier[i], NTHREADS >> i);
[256]111    }
112
[269]113    ////////////////////////
114    // Array Initialization
[256]115
[271]116    for (i = IPT * thread_id; i < IPT * (thread_id + 1); i++)
[256]117    {
[269]118        array0[i] = rand();
[256]119    }
120
[257]121    ///////////////////////////////////
122    // Parallel sort of array elements
[256]123
[269]124    printf("[ Thread %d ] Stage 0: Processor Sorting...\n\r", thread_id);
[257]125
[271]126    bubbleSort(array0, IPT, IPT * thread_id);
[256]127
[269]128    printf("[ Thread %d ] Finishing Stage 0\n\r", thread_id);
[257]129
[271]130    for (i = 0; i < __builtin_ctz(NTHREADS); i++)
[256]131    {
132        asm volatile ("sync");
133        barrier_wait(&barrier[i]);
134
[269]135        if((thread_id % (2 << i)) != 0)
136        {
137            printf("[ Thread %d ] Quits\n\r", thread_id);
138            exit();
139        }
[257]140
[269]141        printf("[ Thread %d ] Stage %d: Starting...\n\r", thread_id, i+1);
[256]142
143        if((i % 2) == 0)
144        {
145            src_array = &array0[0];
146            dst_array = &array1[0];
147        }
148        else
149        {
150            src_array = &array1[0];
151            dst_array = &array0[0];
152        }
153
154        merge(src_array, dst_array
[271]155                , IPT << i
156                , IPT * thread_id
157                , IPT * (thread_id + (1 << i))
158                , IPT * thread_id
[256]159                );
160
[269]161        printf("[ Thread %d ] Finishing Stage %d\n\r", thread_id, i + 1);
[256]162    }
163
164    int success;
165    int failure_index;
166
[257]167    //////////////////////////////
168    // Verify the resulting array
169
[269]170    if(thread_id == 0)
[256]171    {
172        success = 1;
173
174        for(i=0; i<(ARRAY_LENGTH-1); i++)
175        {
176            if(dst_array[i] > dst_array[i+1])
177            {
178
179                success = 0;
180                failure_index = i;
181                break;
182            }
183        }
184
185        if (success)
186        {
[269]187            printf("[ Thread 0 ] Success!!\n\r");
[256]188        }
189        else
190        {
[269]191            printf("[ Thread 0 ] Failure!! Incorrect element: %d\n\r", failure_index);
[256]192
193
194            for(i=0; i<ARRAY_LENGTH; i++)
195            {
196                printf("array[%d] = %d\n", i, dst_array[i]);
197            }
198        }
199    }
200
201    exit();
202}
203
204void bubbleSort(
205        int * array,
206        unsigned int length,
207        unsigned int init_pos)
208{
209    int i;
210    int j;
211    int aux;
212
213    for(i = 0; i < length; i++)
214    {
215        for(j = init_pos; j < (init_pos + length - i - 1); j++)
216        {
217            if(array[j] > array[j + 1])
218            {
219                aux          = array[j + 1];
220                array[j + 1] = array[j];
221                array[j]     = aux;
222            }
223        }
224    }
225}
226
227void merge(
228        int * array,
229        int * result,
230        int length,
231        int init_pos_a,
232        int init_pos_b,
233        int init_pos_result)
234{
235    int i;
236    int j;
237    int k;
238
239    i = 0;
240    j = 0;
241    k = init_pos_result;
242
243    while((i < length) || (j < length))
244    {
245        if((i < length) && (j < length))
246        {
247            if(array[init_pos_a + i] < array[init_pos_b + j])
248            {
249                result[k++] = array[init_pos_a + i];
250                i++;
251            }
252            else
253            {
254                result[k++] = array[init_pos_b + j];
255                j++;
256            }
257        }
258        else if(i < length)
259        {
260            result[k++] = array[init_pos_a + i];
261            i++;
262        }
263        else
264        {
265            result[k++] = array[init_pos_b + j];
266            j++;
267        }
268    }
269}
270
271/* vim: tabstop=4 : shiftwidth=4 : expandtab
272*/
Note: See TracBrowser for help on using the repository browser.