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

Last change on this file since 287 was 271, checked in by cfuguet, 11 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
Line 
1///////////////////////////////////////////////////////////////////////////////
2// File :
3//     
4//      main.c
5//
6// Date :
7//     
8//      November 2013
9//
10// Author :
11//
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///////////////////////////////////////////////////////////////////////////////
34
35#include "stdio.h"
36#include "hard_config.h"
37#include "barrier.h"
38
39//////////////////////////////////////////////////////////////////////////
40// The NTHREADS constant must be modified depending on the desired number of
41// threads
42
43#define NTHREADS        8
44#define ARRAY_LENGTH    (NTHREADS * 128)
45#define IPT             (ARRAY_LENGTH / NTHREADS) // ITEMS PER THREAD
46
47////////////////////////////////////////////////////////////////////////////////
48// Processors other than 0 display algorithm state
49// The processor 0 always displays some information so this does not affect him
50
51#define VERBOSE         1
52
53///////////////////////////////////////////////////////////////////////
54// Define printf according to verbosity option and number of available
55// TTY
56
57#if (VERBOSE == 1)
58#   define printf(...)     giet_tty_printf(__VA_ARGS__)
59#   define puts(...)       giet_tty_puts(__VA_ARGS__)
60#else       // VERBOSE == 0
61#   define printf(...)
62#   define puts(...)
63#endif
64
65#define task0_printf(...) if(thread_id == 0) giet_tty_printf(__VA_ARGS__)
66
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
89///////////////////////////////////////////////////
90// This application support at most 256 processors
91// Number of barriers = log2(NTHREADS)
92
93giet_barrier_t barrier[8];
94
95__attribute__ ((constructor)) void sort()
96{
97    int thread_id = giet_thread_id();
98
99    int * src_array;
100    int * dst_array;
101    int i;
102
103    printf("[ Thread %d ] Initializing vector and barriers...\n\r", thread_id);
104
105    ///////////////////////////
106    // Barriers Initialization
107
108    for (i = 0; i < __builtin_ctz(NTHREADS); i++)
109    {
110        barrier_init(&barrier[i], NTHREADS >> i);
111    }
112
113    ////////////////////////
114    // Array Initialization
115
116    for (i = IPT * thread_id; i < IPT * (thread_id + 1); i++)
117    {
118        array0[i] = rand();
119    }
120
121    ///////////////////////////////////
122    // Parallel sort of array elements
123
124    printf("[ Thread %d ] Stage 0: Processor Sorting...\n\r", thread_id);
125
126    bubbleSort(array0, IPT, IPT * thread_id);
127
128    printf("[ Thread %d ] Finishing Stage 0\n\r", thread_id);
129
130    for (i = 0; i < __builtin_ctz(NTHREADS); i++)
131    {
132        asm volatile ("sync");
133        barrier_wait(&barrier[i]);
134
135        if((thread_id % (2 << i)) != 0)
136        {
137            printf("[ Thread %d ] Quits\n\r", thread_id);
138            exit();
139        }
140
141        printf("[ Thread %d ] Stage %d: Starting...\n\r", thread_id, i+1);
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
155                , IPT << i
156                , IPT * thread_id
157                , IPT * (thread_id + (1 << i))
158                , IPT * thread_id
159                );
160
161        printf("[ Thread %d ] Finishing Stage %d\n\r", thread_id, i + 1);
162    }
163
164    int success;
165    int failure_index;
166
167    //////////////////////////////
168    // Verify the resulting array
169
170    if(thread_id == 0)
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        {
187            printf("[ Thread 0 ] Success!!\n\r");
188        }
189        else
190        {
191            printf("[ Thread 0 ] Failure!! Incorrect element: %d\n\r", failure_index);
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.