|
|
|
|
#ifndef TRAFFIC_TASK_GRAPH_H
|
#ifndef TRAFFIC_TASK_GRAPH_H
|
#define TRAFFIC_TASK_GRAPH_H
|
#define TRAFFIC_TASK_GRAPH_H
|
|
|
|
|
|
|
#define SET_AUTO -1
|
#define SET_AUTO -1
|
|
|
|
|
|
|
#define MAX_LINE_LEN 1000
|
#define MAX_LINE_LEN 1000
|
#define DEAFULT_INIT_WEIGHT 1
|
#define DEAFULT_INIT_WEIGHT 1
|
#define DEAFULT_MIN_PCK_SIZE 8 // must be larger than 1
|
#define DEAFULT_MIN_PCK_SIZE 8 // must be larger than 1
|
|
|
|
|
|
|
typedef struct INDEX_INFO{
|
typedef struct INDEX_INFO{
|
unsigned int active_index;
|
unsigned int active_index;
|
unsigned int total_index;
|
unsigned int total_index;
|
} index_t;
|
} index_t;
|
|
|
|
|
|
|
typedef struct TRAFFIC_TASK {
|
typedef struct TRAFFIC_TASK {
|
char enable;
|
char enable;
|
unsigned int src;
|
unsigned int src;
|
unsigned int dst; // ID of the destination node (PE)
|
unsigned int dst; // ID of the destination node (PE)
|
unsigned int bytes;
|
unsigned int bytes;
|
unsigned int initial_weight;
|
unsigned int initial_weight;
|
unsigned int min_pck_size; //in flit
|
unsigned int min_pck_size; //in flit
|
unsigned int max_pck_size; //in flit
|
unsigned int max_pck_size; //in flit
|
|
|
unsigned int avg_pck_size; //in flit
|
unsigned int avg_pck_size; //in flit
|
unsigned int estimated_total_pck_num;
|
unsigned int estimated_total_pck_num;
|
unsigned int burst_size;
|
unsigned int burst_size;
|
float injection_rate;
|
float injection_rate;
|
unsigned int jnjct_var;
|
unsigned int jnjct_var;
|
|
|
unsigned int pck_sent;
|
unsigned int pck_sent;
|
unsigned int byte_sent;
|
unsigned int byte_sent;
|
unsigned int burst_sent;
|
unsigned int burst_sent;
|
} task_t;
|
} task_t;
|
|
|
|
|
|
|
typedef struct node {
|
typedef struct node {
|
task_t task;
|
task_t task;
|
struct node * next;
|
struct node * next;
|
} node_t;
|
} node_t;
|
|
|
|
|
|
|
unsigned int total_active_routers=0;
|
unsigned int total_active_routers=0;
|
unsigned int task_graph_total_pck_num=0;
|
unsigned int task_graph_total_pck_num=0;
|
node_t * task_graph_data[NC];
|
node_t * task_graph_data[NE];
|
index_t task_graph_abstract[NC];
|
index_t task_graph_abstract[NE];
|
|
|
|
|
|
|
|
|
void push(node_t ** head, task_t task) {
|
void push(node_t ** head, task_t task) {
|
node_t * new_node;
|
node_t * new_node;
|
new_node = (node_t *) malloc(sizeof(node_t));
|
new_node = (node_t *) malloc(sizeof(node_t));
|
if( new_node == NULL){
|
if( new_node == NULL){
|
printf("Error: cannot allocate memory in push function\n");
|
printf("Error: cannot allocate memory in push function\n");
|
exit(1);
|
exit(1);
|
}
|
}
|
new_node->task=task;
|
new_node->task=task;
|
new_node->next = *head;
|
new_node->next = *head;
|
*head = new_node;
|
*head = new_node;
|
}
|
}
|
|
|
int pop(node_t ** head) {
|
int pop(node_t ** head) {
|
// int retval = -1;
|
// int retval = -1;
|
node_t * next_node = NULL;
|
node_t * next_node = NULL;
|
|
|
if (*head == NULL) {
|
if (*head == NULL) {
|
return -1;
|
return -1;
|
}
|
}
|
|
|
next_node = (*head)->next;
|
next_node = (*head)->next;
|
//retval = (*head)->val;
|
//retval = (*head)->val;
|
free(*head);
|
free(*head);
|
*head = next_node;
|
*head = next_node;
|
return 1;
|
return 1;
|
//return retval;
|
//return retval;
|
}
|
}
|
|
|
|
|
int remove_by_index(node_t ** head, int n) {
|
int remove_by_index(node_t ** head, int n) {
|
int i = 0;
|
int i = 0;
|
// int retval = -1;
|
// int retval = -1;
|
node_t * current = *head;
|
node_t * current = *head;
|
node_t * temp_node = NULL;
|
node_t * temp_node = NULL;
|
|
|
if (n == 0) {
|
if (n == 0) {
|
return pop(head);
|
return pop(head);
|
}
|
}
|
|
|
for (i = 0; i < n-1; i++) {
|
for (i = 0; i < n-1; i++) {
|
if (current->next == NULL) {
|
if (current->next == NULL) {
|
return -1;
|
return -1;
|
}
|
}
|
current = current->next;
|
current = current->next;
|
}
|
}
|
|
|
temp_node = current->next;
|
temp_node = current->next;
|
//retval = temp_node->val;
|
//retval = temp_node->val;
|
current->next = temp_node->next;
|
current->next = temp_node->next;
|
free(temp_node);
|
free(temp_node);
|
return 1;
|
return 1;
|
|
|
}
|
}
|
|
|
|
|
int update_by_index(node_t * head,int loc, task_t task) {
|
int update_by_index(node_t * head,int loc, task_t task) {
|
node_t * current = head;
|
node_t * current = head;
|
int i;
|
int i;
|
for (i=0;i<loc && current != NULL;i++){
|
for (i=0;i<loc && current != NULL;i++){
|
current = current->next;
|
current = current->next;
|
|
|
}
|
}
|
if(current == NULL) return 0;
|
if(current == NULL) return 0;
|
current->task=task;
|
current->task=task;
|
return 1;
|
return 1;
|
|
|
}
|
}
|
|
|
|
|
int read(node_t * head, int loc, task_t * task ) {
|
int read(node_t * head, int loc, task_t * task ) {
|
node_t * current = head;
|
node_t * current = head;
|
int i;
|
int i;
|
for (i=0;i<loc && current != NULL;i++){
|
for (i=0;i<loc && current != NULL;i++){
|
current = current->next;
|
current = current->next;
|
|
|
}
|
}
|
if(current == NULL) return 0;
|
if(current == NULL) return 0;
|
*task = current->task;
|
*task = current->task;
|
return 1;
|
return 1;
|
}
|
}
|
|
|
|
|
char* removewhiteSpacses (char * oldstr ) {
|
char* removewhiteSpacses (char * oldstr ) {
|
char *newstr = (char*) malloc(strlen(oldstr)+1);
|
char *newstr = (char*) malloc(strlen(oldstr)+1);
|
char *np = newstr, *op = oldstr;
|
char *np = newstr, *op = oldstr;
|
do {
|
do {
|
if (*op != ' ' && *op != '\t')
|
if (*op != ' ' && *op != '\t')
|
*np++ = *op;
|
*np++ = *op;
|
} while (*op++);
|
} while (*op++);
|
return newstr;
|
return newstr;
|
}
|
}
|
|
|
|
|
int extract_traffic_data ( char * str, task_t* st)
|
int extract_traffic_data ( char * str, task_t* st)
|
{
|
{
|
|
|
unsigned int src;
|
unsigned int src;
|
unsigned int dst; // ID of the destination node (PE)
|
unsigned int dst; // ID of the destination node (PE)
|
unsigned int bytes;
|
unsigned int bytes;
|
unsigned int initial_weight;
|
unsigned int initial_weight;
|
unsigned int min_pck_size; //in flit
|
unsigned int min_pck_size; //in flit
|
unsigned int max_pck_size; //in flit
|
unsigned int max_pck_size; //in flit
|
unsigned int burst;
|
unsigned int burst;
|
float inject_rate;
|
float inject_rate;
|
int jnjct_var;
|
int jnjct_var;
|
|
|
int n;
|
int n;
|
n=sscanf( str, "%u,%u,%u,%u,%u,%u,%u,%f,%u",&src, &dst, &bytes, &initial_weight, &min_pck_size, &max_pck_size,&burst,&inject_rate,&jnjct_var);
|
n=sscanf( str, "%u,%u,%u,%u,%u,%u,%u,%f,%u",&src, &dst, &bytes, &initial_weight, &min_pck_size, &max_pck_size,&burst,&inject_rate,&jnjct_var);
|
|
|
if (n<3) return 0;
|
if (n<3) return 0;
|
|
|
st->src = src;
|
st->src = src;
|
st->dst=dst;
|
st->dst=dst;
|
st->bytes=bytes;
|
st->bytes=bytes;
|
st->initial_weight=(n>3 && initial_weight >0 )? initial_weight :DEAFULT_INIT_WEIGHT;
|
st->initial_weight=(n>3 && initial_weight >0 )? initial_weight :DEAFULT_INIT_WEIGHT;
|
st->min_pck_size= (n>4 && min_pck_size>1 )? min_pck_size : DEAFULT_MIN_PCK_SIZE;
|
st->min_pck_size= (n>4 && min_pck_size>1 )? min_pck_size : DEAFULT_MIN_PCK_SIZE;
|
st->max_pck_size= (n>5 && max_pck_size >= st->min_pck_size )? max_pck_size : st->min_pck_size;
|
st->max_pck_size= (n>5 && max_pck_size >= st->min_pck_size )? max_pck_size : st->min_pck_size;
|
st->burst_size = (n>6 )? burst : SET_AUTO;
|
st->burst_size = (n>6 )? burst : SET_AUTO;
|
st->injection_rate= (n>7 )? inject_rate : SET_AUTO;
|
st->injection_rate= (n>7 )? inject_rate : SET_AUTO;
|
st->jnjct_var= (n>8 )? jnjct_var : 20;
|
st->jnjct_var= (n>8 )? jnjct_var : 20;
|
//
|
//
|
st->avg_pck_size= (st->min_pck_size + st->max_pck_size)/2;
|
st->avg_pck_size= (st->min_pck_size + st->max_pck_size)/2;
|
st->estimated_total_pck_num = (bytes*8) /(st->avg_pck_size*Fpay);
|
st->estimated_total_pck_num = (bytes*8) /(st->avg_pck_size*Fpay);
|
if(st->estimated_total_pck_num==0) st->estimated_total_pck_num= 1;
|
if(st->estimated_total_pck_num==0) st->estimated_total_pck_num= 1;
|
task_graph_total_pck_num=task_graph_total_pck_num+st->estimated_total_pck_num;
|
task_graph_total_pck_num=task_graph_total_pck_num+st->estimated_total_pck_num;
|
|
|
st->pck_sent=0;
|
st->pck_sent=0;
|
st->byte_sent=0;
|
st->byte_sent=0;
|
st->burst_sent=0;
|
st->burst_sent=0;
|
|
|
return 1;
|
return 1;
|
}
|
}
|
|
|
int calcualte_traffic_parameters(node_t * head[NC],index_t (* info)){
|
int calcualte_traffic_parameters(node_t * head[NE],index_t (* info)){
|
int i,j;
|
int i,j;
|
task_t task;
|
task_t task;
|
|
|
unsigned int max_bytes=0,accum[NC];
|
unsigned int max_bytes=0,accum[NE];
|
unsigned int min_total[NC];
|
unsigned int min_total[NE];
|
|
|
//find the maximum bytes that an IP sends
|
//find the maximum bytes that an IP sends
|
for(i=0;i<NC;i++){
|
for(i=0;i<NE;i++){
|
|
|
info[i].active_index=-1;
|
info[i].active_index=-1;
|
j=0;
|
j=0;
|
accum[i]=0;
|
accum[i]=0;
|
if(head[i]!=NULL){
|
if(head[i]!=NULL){
|
info[i].active_index=0;
|
info[i].active_index=0;
|
|
|
min_total[i] = -1;
|
min_total[i] = -1;
|
while( read(head[i],j,&task)==1){
|
while( read(head[i],j,&task)==1){
|
accum[i]=accum[i]+task.bytes;
|
accum[i]=accum[i]+task.bytes;
|
if( min_total[i] > task.estimated_total_pck_num) min_total[i] = task.estimated_total_pck_num;
|
if( min_total[i] > task.estimated_total_pck_num) min_total[i] = task.estimated_total_pck_num;
|
j++;
|
j++;
|
}
|
}
|
info[i].total_index=j;
|
info[i].total_index=j;
|
if(max_bytes < accum[i]) max_bytes=accum[i];
|
if(max_bytes < accum[i]) max_bytes=accum[i];
|
}
|
}
|
|
|
}
|
}
|
|
|
|
|
for(i=0;i<NC;i++){
|
for(i=0;i<NE;i++){
|
|
|
j=0;
|
j=0;
|
if(head[i]!=NULL){
|
if(head[i]!=NULL){
|
while( read(head[i],j,&task)==1){
|
while( read(head[i],j,&task)==1){
|
if(task.burst_size ==SET_AUTO) task.burst_size = task.estimated_total_pck_num/min_total[i];
|
if(task.burst_size ==SET_AUTO) task.burst_size = task.estimated_total_pck_num/min_total[i];
|
if(task.injection_rate ==SET_AUTO) task.injection_rate= (float)(200*accum[i] / (3*max_bytes));
|
if(task.injection_rate ==SET_AUTO) task.injection_rate= (float)(200*accum[i] / (3*max_bytes));
|
|
|
update_by_index(head[i],j,task);
|
update_by_index(head[i],j,task);
|
j++;
|
j++;
|
}
|
}
|
}
|
}
|
}
|
}
|
return 0;
|
return 0;
|
}
|
}
|
|
|
|
|
|
|
|
|
|
|
void load_traffic_file(char * file, node_t * head[NC], index_t (* info)){
|
void load_traffic_file(char * file, node_t * head[NE], index_t (* info)){
|
FILE * in;
|
FILE * in;
|
char * line = NULL;
|
char * line = NULL;
|
|
|
task_t st;
|
task_t st;
|
char l[MAX_LINE_LEN];
|
char l[MAX_LINE_LEN];
|
in = fopen(file,"rb");
|
in = fopen(file,"rb");
|
int n,i;
|
int n,i;
|
|
|
if(in == NULL){
|
if(in == NULL){
|
printf("Error: cannot open %s file in read mode!\n",file);
|
printf("Error: cannot open %s file in read mode!\n",file);
|
exit(1);
|
exit(1);
|
}
|
}
|
|
|
for(i=0;i<NC;i++){
|
for(i=0;i<NE;i++){
|
head[i]=NULL;
|
head[i]=NULL;
|
}
|
}
|
|
|
|
|
while (fgets(l,MAX_LINE_LEN, in) != NULL) {
|
while (fgets(l,MAX_LINE_LEN, in) != NULL) {
|
line = removewhiteSpacses(l);
|
line = removewhiteSpacses(l);
|
if(line[0] != '%' && line[0] != 0 ) {
|
if(line[0] != '%' && line[0] != 0 ) {
|
n=extract_traffic_data(line, &st);
|
n=extract_traffic_data(line, &st);
|
if(n==0 || st.dst >=NC) continue;// the destination address must be smaller than NC
|
if(n==0 || st.dst >=NE) continue;// the destination address must be smaller than NC
|
push(&head[st.src],st);
|
push(&head[st.src],st);
|
}
|
}
|
}
|
}
|
fclose(in);
|
fclose(in);
|
calcualte_traffic_parameters(head,info);
|
calcualte_traffic_parameters(head,info);
|
for(i=0;i<NC;i++){
|
for(i=0;i<NE;i++){
|
if(info[i].total_index !=0) total_active_routers++;
|
if(info[i].total_index !=0) total_active_routers++;
|
}
|
}
|
}
|
}
|
|
|
|
|
|
|
|
|
#endif
|
#endif
|
|
|