source: soft/giet_vm/applications/sort/main.c @ 432

Last change on this file since 432 was 432, checked in by alain, 10 years ago

1) Introduce the "applications" directory.
2) Introduce the fixed format (X_WIDTH / Y_WIDTH / P_WIDTH) for processor index in all applications.

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