Changeset 502 for soft/giet_vm/applications/classif/main.c
- Timestamp:
- Feb 8, 2015, 9:20:45 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/applications/classif/main.c
r488 r502 1 /////////////////////////////////////////////////////////////////////////////////////// //1 /////////////////////////////////////////////////////////////////////////////////////// 2 2 // File : main.c (for classif application) 3 3 // Date : november 2014 4 4 // author : Alain Greiner 5 /////////////////////////////////////////////////////////////////////////////////////// //5 /////////////////////////////////////////////////////////////////////////////////////// 6 6 // This multi-threaded application takes a stream of Gigabit Ethernet packets, 7 7 // and makes packet analysis and classification, based on the source MAC address. … … 9 9 // component to receive and send packets on the Gigabit Ethernet port. 10 10 // 11 // This application is described as a TCG (Task and Communication Graph) containing 12 // (N+2) tasks per cluster: 11 // It can run on architectures containing up to 16 * 16 clusters, 12 // and up to 8 processors per cluster. 13 // 14 // This application is described as a TCG (Task and Communication Graph) 15 // containing (N+2) tasks per cluster: 13 16 // - one "load" task 17 // - one "store" task 14 18 // - N "analyse" tasks 15 // - one "store" task 16 // The 4 Kbytes containers are diributed (N+2 containers per cluster): 19 // The containers are distributed (N+2 containers per cluster): 17 20 // - one RX container (part of the kernel rx_chbuf), in the kernel heap. 18 21 // - one TX container (part of the kernel tx-chbuf), in the kernel heap. … … 30 33 // The MWMR fifo descriptors array is defined as a global variable in cluster[0][0]. 31 34 // 32 // Initialisation is done in two steps by the "load" tasks: 33 // - Task "load" in cluster[0][0] initialises NIC & CMA channel, and initialises 34 // the barrier between all "load" tasks. Other "load" tasks are waiting on the 35 // global_sync synchronisation variable. 36 // - In each cluster[x][y], the "load" task allocates the working containers 37 // and the MWMR fifos descriptors in the local heap. 38 // The "analyse" tasks are waiting on the sync[x][y] variables. 35 // Initialisation is done in two steps by the "load" & "store" tasks: 36 // - Task "load" in cluster[0][0] initialises the barrier between all "load" tasks, 37 // allocates NIC & CMA RX channel, and starts the NIC_CMA RX transfer. 38 // Other "load" tasks are waiting on the load_sync synchronisation variable. 39 // Task "store" in cluster[0][0] initialises the barrier between all "store" tasks, 40 // allocates NIC & CMA TX channels, and starts the NIC_CMA TX transfer. 41 // Other "store" tasks are waiting on the store_sync synchronisation variable. 42 // - When this global initialisation is completed, the "load" task in all clusters 43 // allocates the working containers and the MWMR fifos descriptors from the 44 // user local heap. In each cluster, the "analyse" and "store" tasks are waiting 45 // the local initialisation completion on the local_sync[x][y] variables. 39 46 // 40 // Instrumentation results display is done by the "store" task in cluster[0][0]41 // when all "store" tasks completed the number of clusters specified by the42 // CONTAINERS_MAX parameter.43 //44 47 // When initialisation is completed, all tasks loop on containers: 45 48 // 1) The "load" task get an empty working container from the fifo_s2l, … … 47 50 // and transfer ownership of this container to one "analysis" task by writing 48 51 // into the fifo_l2a. 49 //50 52 // 2) The "analyse" task get one working container from the fifo_l2a, analyse 51 53 // each packet header, compute the packet type (depending on the SRC MAC address), 52 54 // increment the correspondint classification counter, and transpose the SRC 53 55 // and the DST MAC addresses fot TX tranmission. 54 //55 56 // 3) The "store" task transfer get a full working container from the fifo_a2s, 56 57 // transfer this user container content to the the kernel tx_chbuf, 57 58 // and transfer ownership of this empty container to the "load" task by writing 58 59 // into the fifo_s2l. 59 // 60 // This application uses the following hardware parameters (hard_config.h file): 61 // - X_SIZE : number of clusters in a row 62 // - Y_SIZE : number of clusters in a column 63 // - NB_PROCS_MAX : number of processors per cluster 64 ///////////////////////////////////////////////////////////////////////////////////////// 60 // 61 // Instrumentation results display is done by the "store" task in cluster[0][0] 62 // when all "store" tasks completed the number of clusters specified by the 63 // CONTAINERS_MAX parameter. 64 /////////////////////////////////////////////////////////////////////////////////////// 65 65 66 66 #include "stdio.h" 67 #include " barrier.h"67 #include "user_barrier.h" 68 68 #include "malloc.h" 69 69 #include "user_lock.h" 70 70 #include "mwmr_channel.h" 71 #include "hard_config.h" 72 73 #define CONTAINERS_MAX 5 74 #define VERBOSE_ANALYSE 1 75 #define ANALYSIS_TASKS (NB_PROCS_MAX - 2) 76 77 ///////////////////////////////////////////////////////////////////////////////////////// 71 72 #define X_SIZE_MAX 16 73 #define Y_SIZE_MAX 16 74 #define NPROCS_MAX 8 75 #define CONTAINERS_MAX 500 76 #define VERBOSE_ANALYSE 0 77 78 /////////////////////////////////////////////////////////////////////////////////////// 78 79 // Global variables 79 80 // The MWMR channels (descriptors and buffers), as well as the working containers … … 81 82 // But the pointers on these distributed structures are shared arrays 82 83 // stored in cluster[0][0]. 83 /////////////////////////////////////////////////////////////////////////////////////// //84 85 // pointers on distributed temp[x][y][n]containers86 unsigned int* container[X_SIZE ][Y_SIZE][ANALYSIS_TASKS];84 /////////////////////////////////////////////////////////////////////////////////////// 85 86 // pointers on distributed containers 87 unsigned int* container[X_SIZE_MAX][Y_SIZE_MAX][NPROCS_MAX-2]; 87 88 88 89 // pointers on distributed mwmr fifos containing : temp[x][y][l] container descriptors 89 mwmr_channel_t* mwmr_l2a[X_SIZE ][Y_SIZE];90 mwmr_channel_t* mwmr_a2s[X_SIZE ][Y_SIZE];91 mwmr_channel_t* mwmr_s2l[X_SIZE ][Y_SIZE];90 mwmr_channel_t* mwmr_l2a[X_SIZE_MAX][Y_SIZE_MAX]; 91 mwmr_channel_t* mwmr_a2s[X_SIZE_MAX][Y_SIZE_MAX]; 92 mwmr_channel_t* mwmr_s2l[X_SIZE_MAX][Y_SIZE_MAX]; 92 93 93 94 // local synchros signaling local MWMR fifos initialisation completion 94 unsigned int local_sync[X_SIZE][Y_SIZE];95 volatile unsigned int local_sync[X_SIZE_MAX][Y_SIZE_MAX]; 95 96 96 97 // global synchro signaling global initialisation completion 97 unsigned int load_sync = 0;98 unsigned int store_sync = 0;98 volatile unsigned int load_sync = 0; 99 volatile unsigned int store_sync = 0; 99 100 100 101 // instrumentation counters 101 102 unsigned int counter[16]; 102 103 103 // distributed barriers (between "load" and "store" tasks) 104 giet_sbt_barrier_t rx_barrier; 105 giet_sbt_barrier_t tx_barrier; 104 // distributed barrier between "load" tasks 105 giet_sqt_barrier_t rx_barrier; 106 107 // distributed barrier between "store" tasks 108 giet_sqt_barrier_t tx_barrier; 106 109 107 110 // NIC_RX and NIC_TX channel index … … 113 116 ///////////////////////////////////////// 114 117 { 118 // each "load" task get platform parameters 119 unsigned int x_size; // number of clusters in a row 120 unsigned int y_size; // number of clusters in a column 121 unsigned int nprocs; // number of processors per cluster 122 giet_procs_number( &x_size, &y_size, &nprocs ); 123 124 giet_assert( (x_size <= X_SIZE_MAX) && 125 (y_size <= Y_SIZE_MAX) && 126 (nprocs <= NPROCS_MAX) , 127 "[CLASSIF ERROR] illegal platform parameters" ); 128 115 129 // each "load" task get processor identifiers 116 130 unsigned int x; … … 119 133 giet_proc_xyp( &x, &y, &l ); 120 134 121 // "load" task[0][0] initialises barrier between load tasks,135 // "load" task[0][0] initialises barrier between all load tasks, 122 136 // allocates the NIC & CMA RX channels, and start the NIC_CMA RX transfer. 123 137 // Other "load" tasks wait completion 124 138 if ( (x==0) && (y==0) ) 125 139 { 126 giet_shr_printf("\n*** Task load on P[%d][%d][%d] starts at cycle %d\n", 127 x , y , l , giet_proctime() ); 140 giet_shr_printf("\n*** Task load on P[%d][%d][%d] starts at cycle %d\n" 141 " x_size = %d / y_size = %d / nprocs = %d\n", 142 x , y , l , giet_proctime() , x_size, y_size, nprocs ); 128 143 129 s bt_barrier_init( &rx_barrier, X_SIZE*Y_SIZE, 1 );130 nic_rx_channel = giet_nic_rx_alloc( );144 sqt_barrier_init( &rx_barrier, x_size , y_size , 1 ); 145 nic_rx_channel = giet_nic_rx_alloc( x_size , y_size ); 131 146 giet_nic_rx_start( nic_rx_channel ); 132 147 load_sync = 1; … … 137 152 } 138 153 139 // all load tasks allocatecontainers[x][y][n] (from local heap)154 // each load tasks allocates containers[x][y][n] (from local heap) 140 155 // and register pointers in the local stack 141 156 unsigned int n; 142 unsigned int* cont[ANALYSIS_TASKS]; 143 144 for ( n = 0 ; n < ANALYSIS_TASKS ; n++ ) 157 unsigned int* cont[NPROCS_MAX-2]; 158 unsigned int analysis_tasks = nprocs-2; 159 160 for ( n = 0 ; n < analysis_tasks ; n++ ) 145 161 { 146 162 container[x][y][n] = malloc( 4096 ); … … 148 164 } 149 165 150 // all load tasks allocatedata buffers for mwmr fifos (from local heap)151 unsigned int* data_l2a = malloc( ANALYSIS_TASKS<<2 );152 unsigned int* data_a2s = malloc( ANALYSIS_TASKS<<2 );153 unsigned int* data_s2l = malloc( ANALYSIS_TASKS<<2 );154 155 // all load tasks allocatemwmr fifos descriptors (from local heap)166 // each load task allocates data buffers for mwmr fifos (from local heap) 167 unsigned int* data_l2a = malloc( analysis_tasks<<2 ); 168 unsigned int* data_a2s = malloc( analysis_tasks<<2 ); 169 unsigned int* data_s2l = malloc( analysis_tasks<<2 ); 170 171 // each load task allocates mwmr fifos descriptors (from local heap) 156 172 mwmr_l2a[x][y] = malloc( sizeof(mwmr_channel_t) ); 157 173 mwmr_a2s[x][y] = malloc( sizeof(mwmr_channel_t) ); 158 174 mwmr_s2l[x][y] = malloc( sizeof(mwmr_channel_t) ); 159 175 160 // all "load" tasks registerlocal pointers on mwmr fifos in local stack176 // each load task registers local pointers on mwmr fifos in local stack 161 177 mwmr_channel_t* fifo_l2a = mwmr_l2a[x][y]; 162 178 mwmr_channel_t* fifo_a2s = mwmr_a2s[x][y]; 163 179 mwmr_channel_t* fifo_s2l = mwmr_s2l[x][y]; 164 180 165 // all "load" tasks initialiselocal mwmr fifos descriptors181 // each load task initialises local mwmr fifos descriptors 166 182 // ( width = 4 bytes / depth = number of analysis tasks ) 167 mwmr_init( fifo_l2a , data_l2a , 1 , ANALYSIS_TASKS);168 mwmr_init( fifo_a2s , data_a2s , 1 , ANALYSIS_TASKS);169 mwmr_init( fifo_s2l , data_s2l , 1 , ANALYSIS_TASKS);183 mwmr_init( fifo_l2a , data_l2a , 1 , analysis_tasks ); 184 mwmr_init( fifo_a2s , data_a2s , 1 , analysis_tasks ); 185 mwmr_init( fifo_s2l , data_s2l , 1 , analysis_tasks ); 170 186 171 187 172 // all "load" tasks initialiselocal containers as empty in fifo_s2l173 for ( n = 0 ; n < ANALYSIS_TASKS; n++ ) mwmr_write( fifo_s2l , &n , 1 );174 175 // each "load"task[x][y] signals mwmr fifos initialisation completion188 // each load task initialises local containers as empty in fifo_s2l 189 for ( n = 0 ; n < analysis_tasks ; n++ ) mwmr_write( fifo_s2l , &n , 1 ); 190 191 // each load task[x][y] signals mwmr fifos initialisation completion 176 192 // to other tasks in same cluster[x][y] 177 193 local_sync[x][y] = 1; 178 194 179 // "load"task[0][0] displays status195 // load task[0][0] displays status 180 196 if ( (x==0) && (y==0) ) 181 197 giet_shr_printf("\n*** Task load on P[%d,%d,%d] enters main loop at cycle %d\n" … … 192 208 (unsigned int)fifo_s2l, (unsigned int)data_s2l, 193 209 (unsigned int)cont[0], 194 X_SIZE, Y_SIZE, NB_PROCS_MAX);210 x_size, y_size, nprocs ); 195 211 196 212 ///////////////////////////////////////////////////////////// 197 // All "load"tasks enter the main loop (on containers)198 unsigned int count = 0; // loaded containers count199 unsigned int index; // available container index200 unsigned int* temp; // pointer on available container213 // All load tasks enter the main loop (on containers) 214 unsigned int count = 0; // loaded containers count 215 unsigned int index; // available container index 216 unsigned int* temp; // pointer on available container 201 217 202 218 while ( count < CONTAINERS_MAX ) 203 219 { 204 // get one empty co untindex from fifo_s2l220 // get one empty container index from fifo_s2l 205 221 mwmr_read( fifo_s2l , &index , 1 ); 206 222 temp = cont[index]; 207 223 208 // get one co untfrom kernel rx_chbuf224 // get one container from kernel rx_chbuf 209 225 giet_nic_rx_move( nic_rx_channel, temp ); 210 226 … … 213 229 unsigned int nwords = temp[0] >> 16; 214 230 215 if ( (x== X_SIZE-1) && (y==Y_SIZE-1) )231 if ( (x==0) && (y==0) ) 216 232 giet_shr_printf("\n*** Task load on P[%d,%d,%d] get container %d at cycle %d" 217 233 " : %d packets / %d words\n", 218 234 x, y, l, count, giet_proctime(), npackets, nwords ); 219 235 220 // put the full co untindex to fifo_l2a236 // put the full container index to fifo_l2a 221 237 mwmr_write( fifo_l2a, &index , 1 ); 222 238 … … 225 241 226 242 // all "load" tasks synchronise before stats 227 s bt_barrier_wait( &rx_barrier );243 sqt_barrier_wait( &rx_barrier ); 228 244 229 245 // "load" task[0][0] stops the NIC_CMA RX transfer and displays stats … … 244 260 ////////////////////////////////////////// 245 261 { 262 // each "load" task get platform parameters 263 unsigned int x_size; // number of clusters in row 264 unsigned int y_size; // number of clusters in a column 265 unsigned int nprocs; // number of processors per cluster 266 giet_procs_number( &x_size, &y_size, &nprocs ); 267 246 268 // get processor identifiers 247 269 unsigned int x; … … 250 272 giet_proc_xyp( &x, &y, &l ); 251 273 252 253 274 // "store" task[0][0] initialises the barrier between all "store" tasks, 254 275 // allocates NIC & CMA TX channels, and starts the NIC_CMA TX transfer. … … 256 277 if ( (x==0) && (y==0) ) 257 278 { 258 giet_shr_printf("\n*** Task store on P[%d][%d][%d] starts at cycle %d\n", 259 x , y , l , giet_proctime() ); 279 giet_shr_printf("\n*** Task store on P[%d][%d][%d] starts at cycle %d\n" 280 " x_size = %d / y_size = %d / nprocs = %d\n", 281 x , y , l , giet_proctime() , x_size, y_size, nprocs ); 260 282 261 s bt_barrier_init( &tx_barrier , X_SIZE*Y_SIZE, 1 );262 nic_tx_channel = giet_nic_tx_alloc( );283 sqt_barrier_init( &tx_barrier , x_size , y_size , 1 ); 284 nic_tx_channel = giet_nic_tx_alloc( x_size , y_size ); 263 285 giet_nic_tx_start( nic_tx_channel ); 264 286 store_sync = 1; … … 272 294 while ( local_sync[x][y] == 0 ) asm volatile ("nop"); 273 295 274 // all"store" tasks register pointers on working containers in local stack296 // each "store" tasks register pointers on working containers in local stack 275 297 unsigned int n; 276 unsigned int* cont[ANALYSIS_TASKS]; 277 for ( n = 0 ; n < ANALYSIS_TASKS ; n++ ) 298 unsigned int analysis_tasks = nprocs-2; 299 unsigned int* cont[NPROCS_MAX-2]; 300 301 for ( n = 0 ; n < analysis_tasks ; n++ ) 278 302 { 279 303 cont[n] = container[x][y][n]; … … 318 342 unsigned int nwords = temp[0] >> 16; 319 343 320 if ( (x== X_SIZE-1) && (y==Y_SIZE-1) )344 if ( (x==0) && (y==0) ) 321 345 giet_shr_printf("\n*** Task store on P[%d,%d,%d] get container %d at cycle %d" 322 346 " : %d packets / %d words\n", … … 330 354 331 355 // all "store" tasks synchronise before result display 332 s bt_barrier_wait( &tx_barrier );356 sqt_barrier_wait( &tx_barrier ); 333 357 334 358 // "store" task[0,0] stops NIC_CMA TX transfer and displays results … … 377 401 //////////////////////////////////////////// 378 402 { 403 // each "load" task get platform parameters 404 unsigned int x_size; // number of clusters in row 405 unsigned int y_size; // number of clusters in a column 406 unsigned int nprocs; // number of processors per cluster 407 giet_procs_number( &x_size, &y_size, &nprocs ); 408 379 409 // get processor identifiers 380 410 unsigned int x; … … 385 415 if ( (x==0) && (y==0) ) 386 416 { 387 giet_shr_printf("\n*** Task analyse on P[%d][%d][%d] starts at cycle %d\n", 388 x , y , l , giet_proctime() ); 417 giet_shr_printf("\n*** Task analyse on P[%d][%d][%d] starts at cycle %d\n" 418 " x_size = %d / y_size = %d / nprocs = %d\n", 419 x , y , l , giet_proctime() , x_size, y_size, nprocs ); 389 420 } 390 421 … … 394 425 // all "analyse" tasks register pointers on working containers in local stack 395 426 unsigned int n; 396 unsigned int* cont[ANALYSIS_TASKS]; 397 for ( n = 0 ; n < ANALYSIS_TASKS ; n++ ) 427 unsigned int analysis_tasks = nprocs-2; 428 unsigned int* cont[NPROCS_MAX-2]; 429 for ( n = 0 ; n < analysis_tasks ; n++ ) 398 430 { 399 431 cont[n] = container[x][y][n]; … … 471 503 unsigned int word2 = temp[first + 2]; 472 504 505 #if VERBOSE_ANALYSE 473 506 unsigned long long dst = ((unsigned long long)(word1 & 0xFFFF0000)>>16) | 474 507 (((unsigned long long)word0)<<16); 475 508 unsigned long long src = ((unsigned long long)(word1 & 0x0000FFFF)<<32) | 476 509 ((unsigned long long)word2); 477 #if VERBOSE_ANALYSE478 510 if ( p < 10 ) 479 511 {
Note: See TracChangeset
for help on using the changeset viewer.