Program Specialization of Systems Programs Charles Consel Phoenix Research Group (formerly known as the Compose Group) INRIA -LaBRI October 2005 1 INRIA - LaBRI Phoenix Group Oct-05 Phoenix Group: Research Topics Programming language technology – – – Application areas – – – Operating systems Networking Telecommunications Prototypes – – 2 Program analysis and transformation Program specialization Domain-specific languages Tempo Devil, Plan-P, Spidle, SPL Phoenix Group Oct-05 INRIA - LaBRI Recent Contributors Anne-Françoise Le Meur, University of Lille Sapan Bhatia, PhD student in Phoenix Julia Lawall, University of Copenhagen 3 Phoenix Group Oct-05 INRIA - LaBRI Adaptable Programs: Why, Where, How Introduction 4 INRIA - LaBRI Phoenix Group Oct-05 Adaptable Programs: Why? Program1 Problem 2 Program2 Problem 3 Program3 Adaptable Program … Problem 1 Problem Tool Adapted Program Problem family 5 Program family Phoenix Group Oct-05 INRIA - LaBRI Adaptable Programs: Where? Areas: – – Features: – – – – 6 Operating system components Networking layers Adaptability to a variety of platforms Adaptability to a family of services Adaptability to a variety of states Long-running programs Phoenix Group Oct-05 INRIA - LaBRI Adaptable Programs: How? Program structuring approach: generic programs Generic Program Customization information Specializer Customized Program 7 Phoenix Group Oct-05 INRIA - LaBRI Specialization of System/Networking Code: Challenges System code – – – Program specialization – – – – 8 Legacy usually written in C Generic but optimized code Poor software architecture Specialization of a real-size language (i.e., C) Specialization of a low-level language Specialization at run time (not only compile time) Targeting real-size cases Phoenix Group Oct-05 INRIA - LaBRI Specializing System/Networking Code Synthesis Kernel - Columbia – Synthetix Project – OGI – Ad Hoc manual run-time code generation for system calls [SOSP’89] Methodology for manual specialization [SOSP’95] Tempo - Compose/OGI Automatic specialization [TOCS’01] 9 Sun Remote Procedure Call [ICDCS’98] Incremental Checkpointing [DSN’00] Phoenix Group Oct-05 INRIA - LaBRI Tempo in One Slide! Specialization declarations Program analyses Context/flow/return sensitive binding-time analysis Evaluation-time analysis Action analysis – – – – Program transformations – – – Compile time Run time Data specialization Program specializer: Tempo Languages: C, C++, Java Software architectures Components: – – – IPC RPC Signals TCP/IP Gains: time (and/or) space […SOSP’95, POPL’96, PLDI’99, ECOOP’99, ASE’00, CD’02, EMSOFT’04, LCN’04…] […HOSC’99, HOSC’00, TOCS’01, TOPLAS’03, HOSC’04, SCP’04…] 10 Phoenix Group Oct-05 INRIA - LaBRI Anatomy of Tempo Analysis ctx C program Preprocessing Specialization ctx Compile-time Specializer Postprocessing Run-time specializer Generator Run-time Specializer Specialization ctx Specialized source Specialized binary 11 Phoenix Group Oct-05 INRIA - LaBRI Anatomy of Tempo Analysis ctx C program Preprocessing Specialization ctx Compile-time Specializer Postprocessing Run-time specializer Generator Run-time Specializer Specialization ctx Specialized source Specialized binary 12 Phoenix Group Oct-05 INRIA - LaBRI Integrating Program Specialization in The Software Development Process Part I 13 INRIA - LaBRI Phoenix Group Oct-05 Context Customizable component Family of problems Customizable for a family of problems Customization information Component ? Description of a given problem (a usage context) Component customization Customized component 14 Phoenix Group Oct-05 INRIA - LaBRI Software Component Customization Functional customization – restriction of the behavior ex: JavaBeans Code customization – restriction of the behavior – reduction of the genericity smaller & faster code 15 Phoenix Group Oct-05 INRIA - LaBRI Code customization Scope : – often program fragments How : – ifdef compiler directives – C++ Templates cumbersome, error-prone, difficult to use, no debugger Limitation : – 16 code hard to read, hard to maintain, complex the will of the programmer to encode the transformations Phoenix Group Oct-05 INRIA - LaBRI Example: power int power(int base, int expon) { int accum = 1; while (expon > 0) { accum *= base; expon - - ; } return accum; } 17 Phoenix Group Oct-05 INRIA - LaBRI Example: power int power(int base, int expon) { int accum = 1; while (expon > 0) { accum *= base; expon - - ; } return accum; } Functional customization 18 Phoenix Group Oct-05 INRIA - LaBRI Example: power int power(int base, int expon) { int accum = 1; while (expon > 0) { accum *= base; expon - - ; } return accum; } int power(int base, 3) { int accum = 1; while ( expon > 0) { accum *= base; expon - - ; } return accum; } 19 Functional customization Phoenix Group Oct-05 INRIA - LaBRI Example: power int power(int base, int expon) { int accum = 1; while (expon > 0) { accum *= base; expon - - ; } return accum; } Code customization 20 Phoenix Group Oct-05 INRIA - LaBRI Example: power int power(int base, int expon) { int accum = 1; while (expon > 0) { accum *= base; expon - - ; } return accum; } expon = 3 Code customization int power(int base){ return base*base*base; } 21 Phoenix Group Oct-05 INRIA - LaBRI Example: power int power(int base, int expon) { int accum = 1; while (expon > 0) { accum *= base; expon - - ; } return accum; } expon = 3 int power(int base){ return base*base*base; } 22 Phoenix Group template<int expon> inline int power(const int& base) { return power<expon-1>(base) * base;} template<> inline int power<1>(const int& base) { return base;} template<> inline int power<0>(const int& base) { return 1;} Oct-05 INRIA - LaBRI Example: power int power(int base, int expon) { int accum = 1; while (expon > 0) { accum *= base; expon - - ; } return accum; } expon = 3 int power(int base){ return base*base*base; } 23 Phoenix Group template<int expon> inline int power(const int& base) { return power<expon-1>(base) * base;} template<> inline int power<1>(const int& base) { return base;} template<> inline int power<0>(const int& base) { return 1;} Poor readability Oct-05 INRIA - LaBRI Example: power int power(int base, int expon) { int accum = 1; while (expon > 0) { accum *= base; expon - - ; } return accum; } expon = 3 int power(int base){ return base*base*base; } 24 Phoenix Group template<int expon> inline int power(const int& base) { return power<expon-1>(base) * base;} template<> inline int power<1>(const int& base) { return base;} template<> inline int power<0>(const int& base) { return 1;} Semantic transformation Oct-05 INRIA - LaBRI Example: power int power(int base, int expon) { int accum = 1; while (expon > 0) { accum *= base; expon - - ; } return accum; } expon = 3 int power(int base){ return base*base*base; } template<int expon> inline int power(const int& base) { return power<expon-1>(base) * base;} template<> inline int power<1>(const int& base) { return base;} template<> inline int power<0>(const int& base) { return 1;} power<3> 25 Phoenix Group Oct-05 INRIA - LaBRI Example: power int power(int base, int expon) { int accum = 1; while (expon > 0) { accum *= base; expon - - ; } return accum; } expon = 3 int power(int base){ return base*base*base; } template<int expon> inline int power(const int& base) { return power<expon-1>(base) * base;} template<> inline int power<1>(const int& base) { return base;} template<> inline int power<0>(const int& base) { return 1;} power<2>(base) * base 26 Phoenix Group Oct-05 INRIA - LaBRI Example: power int power(int base, int expon) { int accum = 1; while (expon > 0) { accum *= base; expon - - ; } return accum; } expon = 3 int power(int base){ return base*base*base; } template<int expon> inline int power(const int& base) { return power<expon-1>(base) * base;} template<> inline int power<1>(const int& base) { return base;} template<> inline int power<0>(const int& base) { return 1;} power<1>(base) * base * base 27 Phoenix Group Oct-05 INRIA - LaBRI Example: power int power(int base, int expon) { int accum = 1; while (expon > 0) { accum *= base; expon - - ; } return accum; } expon = 3 int power(int base){ return base*base*base; } template<int expon> inline int power(const int& base) { return power<expon-1>(base) * base;} template<> inline int power<1>(const int& base) { return base;} template<> inline int power<0>(const int& base) { return 1;} base * base * base 28 Phoenix Group Oct-05 INRIA - LaBRI Example: power int power(int base, int expon) { int accum = 1; while (expon > 0) { accum *= base; expon - - ; } return accum; } expon = 3 int power(int base){ return base*base*base; } template<int expon> inline int power(const int& base) { return power<expon-1>(base) * base;} template<> inline int power<1>(const int& base) { return base;} template<> inline int power<0>(const int& base) { return 1;} Do we really get what we wanted ?? base * base * base 29 Phoenix Group Oct-05 INRIA - LaBRI To Summarize Customization information Component ? Customized component 30 Phoenix Group Oct-05 INRIA - LaBRI To Summarize Source code with hardcoded transformations : what to customize & how Customization information Component ? Customized component 31 Phoenix Group Oct-05 INRIA - LaBRI To Summarize Source code with hardcoded transformations : what to customize & how Customization information Component Values ? Customized component 32 Phoenix Group Oct-05 INRIA - LaBRI To Summarize Source code with hardcoded transformations : what to customize & how Customization information Component Values Compiler Customized component 33 Phoenix Group Oct-05 INRIA - LaBRI To Summarize Source code with hardcoded transformations : what to customize & how Customization information Component Compiler Customized component 34 Values Phoenix Group Oct-05 No real guaranty INRIA - LaBRI What We Would Like Source code with hardcoded transformations : what to customize & how Customization information Component Compiler Customized component 35 Values Phoenix Group Oct-05 No real guaranty INRIA - LaBRI What We Would Like Source code What to customize Customization information Values Compiler Customized component 36 Phoenix Group Oct-05 INRIA - LaBRI What We Would Like Source code 37 What to customize Customization information Automatic generation of hardcoded transformations Compiler Code with annotated transformations Customized component Phoenix Group Oct-05 Values INRIA - LaBRI What We Would Like Source code 38 What to customize Customization information Automatic generation of hardcoded transformations Compiler Code with annotated transformations Customized component Phoenix Group Oct-05 Values INRIA - LaBRI What We Would Like Source code 39 What to customize Customization information Automatic generation of hardcoded transformations Compiler Code with annotated transformations Customized component Phoenix Group Oct-05 Values Guaranteed INRIA - LaBRI What We Would Like Source code 40 Values What to customize Customization information Automatic generation of hardcoded transformations Compiler Code with annotated transformations Customized component Phoenix Group Oct-05 Guaranteed INRIA - LaBRI What We Would Like Source code Values What to customize Customization information Automatic generation of hardcoded transformations Compiler Code with annotated transformations Customized component Guaranteed Developer 41 Phoenix Group Oct-05 INRIA - LaBRI What We Would Like Source code Values What to customize Customization information Automatic generation of hardcoded transformations Compiler Code with annotated transformations Customized component Developer 42 Guaranteed User Phoenix Group Oct-05 INRIA - LaBRI Our Approach Component developer Source code Component user Customization scenarios Customizable component Customizable component 43 Customization values Customized component Phoenix Group Oct-05 INRIA - LaBRI Component Developer Source code Customization scenarios Customizable component 44 Phoenix Group Oct-05 INRIA - LaBRI Component Developer Source code Step 1: Developing customizable components Customization scenarios Customizable component 45 Phoenix Group Oct-05 INRIA - LaBRI Component Developer Source code Step 1: Developing customizable components Customization scenarios Declaration language: WHAT are the customization parameters • global variables • function parameters • data structure fields Customizable component 46 Phoenix Group Oct-05 INRIA - LaBRI An example of component : Forward Error Correction Encoders • Prevent losses and errors • Transmit redundant information family of problems 47 Phoenix Group Oct-05 INRIA - LaBRI Encoder Features 48 Phoenix Group Oct-05 INRIA - LaBRI FEC Component Hierarchy encode parity bit _ lbc sys _ code conv _ lbc crc libstring mult mat _ 49 Phoenix Group Oct-05 INRIA - LaBRI Remember power source code int power(int base, int expon) { int accum = 1; while (expon > 0) { accum *= base; expon - - ; } return accum; } 50 Phoenix Group Oct-05 INRIA - LaBRI Remember power source code int power(int base, int expon) { int accum = 1; while (expon > 0) { accum *= base; expon - - ; } return accum; } 51 Phoenix Group Oct-05 INRIA - LaBRI Remember power source code declaration module int power(int base, int expon) { int accum = 1; while (expon > 0) { accum *= base; expon - - ; } return accum; } 52 Module power { Defines { From power.c { Btp :: intern power(D(int) b, S(int) e); };} Exports { Btp; }} Phoenix Group customization parameters other parameters Oct-05 INRIA - LaBRI Remember power source code declaration module int power(int base, int expon) { int accum = 1; while (expon > 0) { accum *= base; expon - - ; } return accum; } 53 Module power { Defines { From power.c { Btp :: intern power(D(int) b, S(int) e); };} Exports { Btp; }} Phoenix Group customization parameters other parameters Oct-05 INRIA - LaBRI Remember power source code declaration module int power(int base, int expon) { int accum = 1; while (expon > 0) { accum *= base; expon - - ; } return accum; } 54 Module power { Defines { From power.c { Btp :: intern power(D(int) b, S(int) e); };} Exports { Btp; }} Phoenix Group customization parameters other parameters Oct-05 INRIA - LaBRI Remember power source code declaration module int power(int base, int expon) { int accum = 1; while (expon > 0) { accum *= base; expon - - ; } return accum; } 55 Module power { Defines { From power.c { Btp :: intern power(D(int) b, S(int) e); };} Exports { Btp; }} Phoenix Group customization parameters other parameters Oct-05 INRIA - LaBRI Remember power source code declaration module int power(int base, int expon) { int accum = 1; while (expon > 0) { accum *= base; expon - - ; } return accum; } 56 Module power { Defines { From power.c { Btp :: intern power(D(int) b, S(int) e); };} Exports { Btp; }} Phoenix Group customization parameters other parameters Oct-05 INRIA - LaBRI Remember power Define: compute needs to perform power calculation Define: power 57 Phoenix Group Oct-05 Component: compute Component: power INRIA - LaBRI Remember power Module compute { Imports { From power.mdl {Btp; }} Defines { From compute.c { Btcomp :: intern compute(D(int) , S(int) , S(int) ) needs { Btp;} };} Exports { Btcomp; } } Module power { Defines { From power.c { Btp :: intern power(D(int) , S(int) ); };} Exports { Btp; } } 58 Phoenix Group Oct-05 Module: compute Module: power INRIA - LaBRI Remember power Module compute { Imports { From power.mdl {Btp; }} Defines { From compute.c { Btcomp :: intern compute(D(int) , S(int) , S(int) ) needs { Btp;} };} Exports { Btcomp; } } Module: compute Customization contract Module power { Defines { From power.c { Btp :: intern power(D(int) , S(int) ); };} Exports { Btp; } } 59 Phoenix Group Oct-05 Module: power INRIA - LaBRI Hierarchies of Sources & Modules encode parity bit _ lbc sys _ code conv _ lbc crc libstring mult mat _ 60 Phoenix Group Oct-05 INRIA - LaBRI Developing Customizable Components 61 Phoenix Group Oct-05 INRIA - LaBRI Developing Customizable Components 62 Phoenix Group Oct-05 INRIA - LaBRI Developing Customizable Components 63 Phoenix Group Oct-05 INRIA - LaBRI Developing Customizable Components 64 Phoenix Group Oct-05 INRIA - LaBRI Developing Customizable Components 65 Phoenix Group Oct-05 INRIA - LaBRI Developing Customizable Components 66 Phoenix Group Oct-05 INRIA - LaBRI Developing Customizable Components 67 Phoenix Group Oct-05 INRIA - LaBRI Developing Customizable Components 68 Phoenix Group Oct-05 INRIA - LaBRI Component Developer Source code Step 1: Developing customizable components Customization scenarios Customizable component 69 Phoenix Group Oct-05 INRIA - LaBRI Component Developer Source code Step 1: Developing customizable components Customization scenarios Step 2: Making customizable components Customizable component 70 Phoenix Group Oct-05 INRIA - LaBRI Making Customizable Components 71 Phoenix Group Oct-05 INRIA - LaBRI Component Developer Source code Step 1: Developing customizable components Customization scenarios Step 2: Making customizable components - Determine HOW - Verify that declared customization is possible Customizable component 72 Phoenix Group Oct-05 INRIA - LaBRI Component Developer Source code Step 1: Developing customizable components Customization scenarios Step 2: Making customizable components Customizable component 73 Guaranteed Phoenix Group Oct-05 INRIA - LaBRI Our Approach Component developer Source code Component user Customization scenarios Customizable component Customizable component 74 Customization values Customized component Phoenix Group Oct-05 INRIA - LaBRI Component User Customizable component Customization values Customized component 75 Phoenix Group Oct-05 INRIA - LaBRI Component User Customizable component Customization values Step 3: Making customized components Customized component 76 Phoenix Group Oct-05 INRIA - LaBRI Generating Customized Components 77 Phoenix Group Oct-05 INRIA - LaBRI Generating Customized Components 78 Phoenix Group Oct-05 INRIA - LaBRI Generating Customized Components 79 Phoenix Group Oct-05 INRIA - LaBRI Component User Customizable component Customization values Step 3: Making customized components Customized component 80 Phoenix Group Oct-05 INRIA - LaBRI Component User Customizable component Customization values Step 3: Making customized components Ready to be integrated 81 Phoenix Group Oct-05 Customized component INRIA - LaBRI #include #include #include #include #include #include #include "encode.h" "parity_bit.h" "lin_b_code.h" "lin_b_code_sys.h" "code_conv.h" "encode_crc.h" "libstring.h" struct data { int longueur; int *v; }; void encode(struct data *donnees, struct code *codage, struct data *result){ struct code if (donnees->longueur != codage->k) { { perror("donnees->longueur != codage->k"); int k; exit(1);} int n; else if (strcmp(codage->type, "parity_bit") == 0) int **matrix; if (result->longueur != codage->k + 1) char *type; { perror("result->longueur != codage->k + 1"); char *opt; exit(1);} }; else parity_bit(codage->k, donnees->v, result->v); else if (strcmp(codage->type, "lin_b_code") == 0) extern void encode(struct data *donnees, struct code *codage, struct data *result); if ((*result).longueur != (*codage).n) { perror ("result->longueur != codage->n"); exit (1);} else if (strcmp(codage->opt, "syst") == 0) lin_b_code_sys(donnees->v, codage->k, codage->n, codage->matrix, result->v); else lin_b_code(donnees->v, codage->k, codage->n, codage->matrix, result->v); else if (strcmp(codage->type, "code_conv") == 0) if ((*result).longueur != (2 * (*codage).k)) { perror ("result->longueur != (2 * codage->k)"); exit (1);} else code_conv(donnees->v, codage->k, result->v); else if (strcmp(codage->type, "crc") == 0) if ((*result).longueur != (*codage).n ) { perror ("result->longueur != codage->n"); exit (1); } else encode_crc(donnees->v, codage->k, codage->n, codage->matrix[0], result->v); else { perror("unknown code type"); extern int strcmp(char *s1, char *s2); exit(1); } } extern void encode_crc(int *donnees, int k, int n, int *poly, int *result); extern void parity_bit(int l, int *vector, int *result); #include "parity_bit.h" void parity_bit(int l, int *vector, int *result) { int res; int i; res = 0; for(i = 0; i < l; i++) { res ^= vector[i]; result[i] = vector[i]; } result[l] = res; extern void code_conv(int *donnees, int l, int *result); extern void lin_b_code_sys(int *vector, int k, int n, int **matrix, int *result); #include "code_conv.h" void code_conv(int *donnees, int k, int *result) { int temp; int i; #include "lin_b_code_sys.h" #include "mult_mat.h" void lin_b_code_sys(int *vector, int k, int n, int **matrix, int *result) { int sub_matrix_size; int i; for (i = 0; i < k - 2; i++) { temp = donnees[i] ^ donnees[i + 2]; result[2 * i + 1] = temp; temp ^= donnees[i + 1]; result[2 * i] = temp; } temp = donnees[k - 2] ^ donnees[k - 1]; result[2 * k - 4] = temp; result[2 * k - 3] = donnees[k - 2]; result[2 * k - 2] = donnees[k - 1]; result[2 * k - 1] = donnees[k - 1]; sub_matrix_size = n - k; mult_mat(vector, k, sub_matrix_size, matrix, result, k); for(i = 0; i < k; i++) result[i] = vector[i]; } } } #include "encode_crc.h" void encode_crc(int *donnees, int k, int n, int *poly, int *result) { int l_poly; int i, j; l_poly = n - k + 1; for (i = 0; i < k; i++) result[i] = donnees[i]; for (i = 0; i < k; i++) if (result[i] == 1) for (j = 0; j < l_poly; j++) result[i + j] ^= poly[j]; for (i = 0; i < k; i++) result[i] = donnees[i]; } extern void lin_b_code(int *vector, int k, int n, int **matrix, int *result); #include "lin_b_code.h" #include "mult_mat.h" void lin_b_code(int *vector, int k, int n, int **matrix, int *result) { mult_mat(vector, k, n, matrix, result, 0); } extern void mult_mat(int *vector, int k, int n, int **matrix, int *result, int indice); #include "mult_mat.h" void mult_mat(int *vector, int k, int n, int **matrix, int *result, int indice) { int temp; int i, j; for(i = 0; i < n; i++) { temp = 0; for(j = 0; j < k; j++) temp ^= vector[j] & matrix[j][i]; result[i + indice] = temp; 82 } } Phoenix Group Oct-05 INRIA - LaBRI #include #include #include #include #include #include #include length in length out type generator opt "encode.h" "parity_bit.h" "lin_b_code.h" "lin_b_code_sys.h" "code_conv.h" "encode_crc.h" "libstring.h" struct data { int longueur; int *v; }; void encode(struct data *donnees, struct code *codage, struct data *result){ struct code if (donnees->longueur != codage->k) { { perror("donnees->longueur != codage->k"); int k; exit(1);} int n; else if (strcmp(codage->type, "parity_bit") == 0) int **matrix; if (result->longueur != codage->k + 1) char *type; { perror("result->longueur != codage->k + 1"); char *opt; exit(1);} }; else parity_bit(codage->k, donnees->v, result->v); else if (strcmp(codage->type, "lin_b_code") == 0) extern void encode(struct data *donnees, struct code *codage, struct data *result); if ((*result).longueur != (*codage).n) { perror ("result->longueur != codage->n"); exit (1);} else if (strcmp(codage->opt, "syst") == 0) lin_b_code_sys(donnees->v, codage->k, codage->n, codage->matrix, result->v); else lin_b_code(donnees->v, codage->k, codage->n, codage->matrix, result->v); else if (strcmp(codage->type, "code_conv") == 0) if ((*result).longueur != (2 * (*codage).k)) { perror ("result->longueur != (2 * codage->k)"); exit (1);} else code_conv(donnees->v, codage->k, result->v); else if (strcmp(codage->type, "crc") == 0) if ((*result).longueur != (*codage).n ) { perror ("result->longueur != codage->n"); exit (1); } else encode_crc(donnees->v, codage->k, codage->n, codage->matrix[0], result->v); else { perror("unknown code type"); extern int strcmp(char *s1, char *s2); exit(1); } } extern void encode_crc(int *donnees, int k, int n, int *poly, int *result); extern void parity_bit(int l, int *vector, int *result); #include "parity_bit.h" void parity_bit(int l, int *vector, int *result) { int res; int i; res = 0; for(i = 0; i < l; i++) { res ^= vector[i]; result[i] = vector[i]; } result[l] = res; extern void code_conv(int *donnees, int l, int *result); extern void lin_b_code_sys(int *vector, int k, int n, int **matrix, int *result); #include "code_conv.h" void code_conv(int *donnees, int k, int *result) { int temp; int i; #include "lin_b_code_sys.h" #include "mult_mat.h" void lin_b_code_sys(int *vector, int k, int n, int **matrix, int *result) { int sub_matrix_size; int i; for (i = 0; i < k - 2; i++) { temp = donnees[i] ^ donnees[i + 2]; result[2 * i + 1] = temp; temp ^= donnees[i + 1]; result[2 * i] = temp; } temp = donnees[k - 2] ^ donnees[k - 1]; result[2 * k - 4] = temp; result[2 * k - 3] = donnees[k - 2]; result[2 * k - 2] = donnees[k - 1]; result[2 * k - 1] = donnees[k - 1]; sub_matrix_size = n - k; mult_mat(vector, k, sub_matrix_size, matrix, result, k); for(i = 0; i < k; i++) result[i] = vector[i]; } } } #include "encode_crc.h" void encode_crc(int *donnees, int k, int n, int *poly, int *result) { int l_poly; int i, j; l_poly = n - k + 1; for (i = 0; i < k; i++) result[i] = donnees[i]; for (i = 0; i < k; i++) if (result[i] == 1) for (j = 0; j < l_poly; j++) result[i + j] ^= poly[j]; for (i = 0; i < k; i++) result[i] = donnees[i]; } extern void lin_b_code(int *vector, int k, int n, int **matrix, int *result); #include "lin_b_code.h" #include "mult_mat.h" void lin_b_code(int *vector, int k, int n, int **matrix, int *result) { mult_mat(vector, k, n, matrix, result, 0); } extern void mult_mat(int *vector, int k, int n, int **matrix, int *result, int indice); #include "mult_mat.h" void mult_mat(int *vector, int k, int n, int **matrix, int *result, int indice) { int temp; int i, j; for(i = 0; i < n; i++) { temp = 0; for(j = 0; j < k; j++) temp ^= vector[j] & matrix[j][i]; result[i + indice] = temp; 83 } } Phoenix Group Oct-05 INRIA - LaBRI #include #include #include #include #include #include #include length in length out type generator opt "encode.h" "parity_bit.h" "lin_b_code.h" "lin_b_code_sys.h" "code_conv.h" "encode_crc.h" "libstring.h" struct data { int longueur; int *v; }; void encode(struct data *donnees, struct code *codage, struct data *result){ struct code if (donnees->longueur != codage->k) { { perror("donnees->longueur != codage->k"); int k; exit(1);} int n; else if (strcmp(codage->type, "parity_bit") == 0) int **matrix; if (result->longueur != codage->k + 1) char *type; { perror("result->longueur != codage->k + 1"); char *opt; exit(1);} }; else parity_bit(codage->k, donnees->v, result->v); else if (strcmp(codage->type, "lin_b_code") == 0) extern void encode(struct data *donnees, struct code *codage, struct data *result); if ((*result).longueur != (*codage).n) { perror ("result->longueur != codage->n"); exit (1);} else if (strcmp(codage->opt, "syst") == 0) lin_b_code_sys(donnees->v, codage->k, codage->n, codage->matrix, result->v); else lin_b_code(donnees->v, codage->k, codage->n, codage->matrix, result->v); else if (strcmp(codage->type, "code_conv") == 0) if ((*result).longueur != (2 * (*codage).k)) { perror ("result->longueur != (2 * codage->k)"); exit (1);} else code_conv(donnees->v, codage->k, result->v); else if (strcmp(codage->type, "crc") == 0) if ((*result).longueur != (*codage).n ) { perror ("result->longueur != codage->n"); exit (1); } else encode_crc(donnees->v, codage->k, codage->n, codage->matrix[0], result->v); else { perror("unknown code type"); extern int strcmp(char *s1, char *s2); exit(1); } } extern void encode_crc(int *donnees, int k, int n, int *poly, int *result); extern void parity_bit(int l, int *vector, int *result); #include "parity_bit.h" void parity_bit(int l, int *vector, int *result) { int res; int i; res = 0; for(i = 0; i < l; i++) { res ^= vector[i]; result[i] = vector[i]; } result[l] = res; extern void code_conv(int *donnees, int l, int *result); extern void lin_b_code_sys(int *vector, int k, int n, int **matrix, int *result); #include "code_conv.h" void code_conv(int *donnees, int k, int *result) { int temp; int i; #include "lin_b_code_sys.h" #include "mult_mat.h" void lin_b_code_sys(int *vector, int k, int n, int **matrix, int *result) { int sub_matrix_size; int i; for (i = 0; i < k - 2; i++) { temp = donnees[i] ^ donnees[i + 2]; result[2 * i + 1] = temp; temp ^= donnees[i + 1]; result[2 * i] = temp; } temp = donnees[k - 2] ^ donnees[k - 1]; result[2 * k - 4] = temp; result[2 * k - 3] = donnees[k - 2]; result[2 * k - 2] = donnees[k - 1]; result[2 * k - 1] = donnees[k - 1]; sub_matrix_size = n - k; mult_mat(vector, k, sub_matrix_size, matrix, result, k); for(i = 0; i < k; i++) result[i] = vector[i]; } } } #include "encode_crc.h" void encode_crc(int *donnees, int k, int n, int *poly, int *result) { int l_poly; int i, j; l_poly = n - k + 1; for (i = 0; i < k; i++) result[i] = donnees[i]; for (i = 0; i < k; i++) if (result[i] == 1) for (j = 0; j < l_poly; j++) result[i + j] ^= poly[j]; for (i = 0; i < k; i++) result[i] = donnees[i]; } extern void lin_b_code(int *vector, int k, int n, int **matrix, int *result); #include "lin_b_code.h" #include "mult_mat.h" void lin_b_code(int *vector, int k, int n, int **matrix, int *result) { mult_mat(vector, k, n, matrix, result, 0); } extern void mult_mat(int *vector, int k, int n, int **matrix, int *result, int indice); #include "mult_mat.h" void mult_mat(int *vector, int k, int n, int **matrix, int *result, int indice) { int temp; int i, j; for(i = 0; i < n; i++) { temp = 0; for(j = 0; j < k; j++) temp ^= vector[j] & matrix[j][i]; result[i + indice] = temp; 84 } } Phoenix Group Oct-05 INRIA - LaBRI length in = 4 length out = 7 type = "lin_b_code” matrix = {{1, 1, 1}, {1, 1, 0}, {1, 0, 0}, {0, 1, 1}} opt = "syst" #include #include #include #include #include #include #include "encode.h" "parity_bit.h" "lin_b_code.h" "lin_b_code_sys.h" "code_conv.h" "encode_crc.h" "libstring.h" struct data { int longueur; int *v; }; void encode(struct data *donnees, struct code *codage, struct data *result){ struct code if (donnees->longueur != codage->k) { { perror("donnees->longueur != codage->k"); int k; exit(1);} int n; else if (strcmp(codage->type, "parity_bit") == 0) int **matrix; if (result->longueur != codage->k + 1) char *type; { perror("result->longueur != codage->k + 1"); char *opt; exit(1);} }; else parity_bit(codage->k, donnees->v, result->v); else if (strcmp(codage->type, "lin_b_code") == 0) extern void encode(struct data *donnees, struct code *codage, struct data *result); if ((*result).longueur != (*codage).n) { perror ("result->longueur != codage->n"); exit (1);} else if (strcmp(codage->opt, "syst") == 0) lin_b_code_sys(donnees->v, codage->k, codage->n, codage->matrix, result->v); else lin_b_code(donnees->v, codage->k, codage->n, codage->matrix, result->v); else if (strcmp(codage->type, "code_conv") == 0) if ((*result).longueur != (2 * (*codage).k)) { perror ("result->longueur != (2 * codage->k)"); exit (1);} else code_conv(donnees->v, codage->k, result->v); else if (strcmp(codage->type, "crc") == 0) if ((*result).longueur != (*codage).n ) { perror ("result->longueur != codage->n"); exit (1); } else encode_crc(donnees->v, codage->k, codage->n, codage->matrix[0], result->v); else { perror("unknown code type"); extern int strcmp(char *s1, char *s2); exit(1); } } extern void encode_crc(int *donnees, int k, int n, int *poly, int *result); extern void parity_bit(int l, int *vector, int *result); #include "parity_bit.h" void parity_bit(int l, int *vector, int *result) { int res; int i; res = 0; for(i = 0; i < l; i++) { res ^= vector[i]; result[i] = vector[i]; } result[l] = res; extern void code_conv(int *donnees, int l, int *result); extern void lin_b_code_sys(int *vector, int k, int n, int **matrix, int *result); #include "code_conv.h" void code_conv(int *donnees, int k, int *result) { int temp; int i; #include "lin_b_code_sys.h" #include "mult_mat.h" void lin_b_code_sys(int *vector, int k, int n, int **matrix, int *result) { int sub_matrix_size; int i; for (i = 0; i < k - 2; i++) { temp = donnees[i] ^ donnees[i + 2]; result[2 * i + 1] = temp; temp ^= donnees[i + 1]; result[2 * i] = temp; } temp = donnees[k - 2] ^ donnees[k - 1]; result[2 * k - 4] = temp; result[2 * k - 3] = donnees[k - 2]; result[2 * k - 2] = donnees[k - 1]; result[2 * k - 1] = donnees[k - 1]; sub_matrix_size = n - k; mult_mat(vector, k, sub_matrix_size, matrix, result, k); for(i = 0; i < k; i++) result[i] = vector[i]; } } } #include "encode_crc.h" void encode_crc(int *donnees, int k, int n, int *poly, int *result) { int l_poly; int i, j; l_poly = n - k + 1; for (i = 0; i < k; i++) result[i] = donnees[i]; for (i = 0; i < k; i++) if (result[i] == 1) for (j = 0; j < l_poly; j++) result[i + j] ^= poly[j]; for (i = 0; i < k; i++) result[i] = donnees[i]; } extern void lin_b_code(int *vector, int k, int n, int **matrix, int *result); #include "lin_b_code.h" #include "mult_mat.h" void lin_b_code(int *vector, int k, int n, int **matrix, int *result) { mult_mat(vector, k, n, matrix, result, 0); } extern void mult_mat(int *vector, int k, int n, int **matrix, int *result, int indice); #include "mult_mat.h" void mult_mat(int *vector, int k, int n, int **matrix, int *result, int indice) { int temp; int i, j; for(i = 0; i < n; i++) { temp = 0; for(j = 0; j < k; j++) temp ^= vector[j] & matrix[j][i]; result[i + indice] = temp; } 85 } Phoenix Group Oct-05 INRIA - LaBRI struct data { int longueur; int *v; }; struct code { int k; int n; int **matrix; char *type; char *opt; }; extern int perror(); extern int exit(); extern void encode_spe(struct data *, struct data *); length in = 4 length out = 7 type = "lin_b_code" matrix = {{1, 1, 1}, {1, 1, 0}, {1, 0, 0}, {0, 1, 1}} opt = "syst" extern void encode_spe/*0*/(struct data *donnees, struct data *result) { { int *lin_b_code_sys_0_result; int *lin_b_code_sys_0_vector; lin_b_code_sys_0_vector = (*donnees).v; lin_b_code_sys_0_result = (*result).v; { int *mult_mat_1_result; int *mult_mat_1_vector; int mult_mat_1_temp; mult_mat_1_vector = lin_b_code_sys_0_vector; mult_mat_1_result = lin_b_code_sys_0_result; mult_mat_1_temp = (((0 ^ (unsigned int)((int)((unsigned int)mult_mat_1_vector[0] & 1))) ^ (unsigned int)((int)((unsigned int)mult_mat_1_vector[1] & 1))) ^ (unsigned int)((int)((unsigned int)mult_mat_1_vector[2] & 1))) ^ (unsigned int)((int)((unsigned int)mult_mat_1_vector[3] & 0)); mult_mat_1_result[4] = mult_mat_1_temp; mult_mat_1_temp = (((0 ^ (unsigned int)((int)((unsigned int)mult_mat_1_vector[0] & 1))) ^ (unsigned int)((int)((unsigned int)mult_mat_1_vector[1] & 1))) ^ (unsigned int)((int)((unsigned int)mult_mat_1_vector[2] & 0))) ^ (unsigned int)((int)((unsigned int)mult_mat_1_vector[3] & 1)); mult_mat_1_result[5] = mult_mat_1_temp; mult_mat_1_temp = (((0 ^ (unsigned int)((int)((unsigned int)mult_mat_1_vector[0] & 1))) ^ (unsigned int)((int)((unsigned int)mult_mat_1_vector[1] & 0))) ^ (unsigned int)((int)((unsigned int)mult_mat_1_vector[2] & 0))) ^ (unsigned int)((int)((unsigned int)mult_mat_1_vector[3] & 1)); mult_mat_1_result[6] = mult_mat_1_temp; } lin_b_code_sys_0_result[0] lin_b_code_sys_0_result[1] lin_b_code_sys_0_result[2] lin_b_code_sys_0_result[3] = = = = lin_b_code_sys_0_vector[0]; lin_b_code_sys_0_vector[1]; lin_b_code_sys_0_vector[2]; lin_b_code_sys_0_vector[3]; } return; } 86 Phoenix Group Oct-05 INRIA - LaBRI Benchmarks Handwritten encoder Generic encoder Customized encoder 87 Phoenix Group Oct-05 INRIA - LaBRI Conclusion Customizable component based on a declarative approach – no hardcoded transformations – module aside from the code – customization properties Environment – visualization tools – compiler for modules code transformation verification Automatic generator of customized component Applications: XDR library, packet filtering, FFT, system interrupts… 88 Phoenix Group Oct-05 INRIA - LaBRI Specialization of Protocol Stacks in OS Kernels Part II 89 INRIA - LaBRI Phoenix Group Oct-05 Introduction High-speed networks require efficient end-system support Efficient end-system support = Efficient applications (clients, servers) + Efficient protocol stacks For high throughput and low service latency, we need efficient applications and protocol stacks 90 Phoenix Group Oct-05 INRIA - LaBRI Introduction High-speed networks require efficient end-system support Efficient end-system support = Efficient applications (clients, servers) + Efficient protocol stacks For high throughput and low service latency, we need efficient applications and protocol stacks 91 Phoenix Group Oct-05 INRIA - LaBRI Overview 92 Some data points Application vs Protocol Stack optimization Program Specialization Specialization of the protocol stack Performance Evaluation Conclusion Phoenix Group Oct-05 INRIA - LaBRI Some data points, to begin with Physical transmission bound vs actual throughput between two Pentium II-700Mhz machines with 100Mbps network (MTU 1500): – – – 93 Max UDP throughput: (70 Mbps) Max TCP throughput: (47 Mbps) HTTP throughput at saturation: (28 Mbps) All limited by the end system Phoenix Group Oct-05 INRIA - LaBRI Application vs Protocol stack optimization Application Protocol Stack GOAL Exploit full b/w of protocol stack Exploit full b/w of hardware EXTENT Limited to application, non-intrusive Implemented in kernel, intrusive DEPLOYED Late Early (With OS) NATURE Application-specific “Application-specific” 94 Phoenix Group Oct-05 INRIA - LaBRI Application vs Protocol stack optimization Application GOAL EXTENT Best left to the application developer Protocol Stack Exploit full b/w of hardware Implemented in kernel, intrusive Early (With OS) DEPLOYED “Application-specific” NATURE 95 Phoenix Group Oct-05 INRIA - LaBRI Application vs Protocol stack optimization Application Protocol Stack Best left to the application developer Need a systematic process to customize… GOAL EXTENT DEPLOYED NATURE 96 Phoenix Group Oct-05 INRIA - LaBRI Program Specialization GENERIC CODE SPECIALIZED CODE CONFIGURATION VALUES 97 Program Specializer (Tempo) Phoenix Group Oct-05 INRIA - LaBRI Program Specialization 98 int tcp_mini_sendmsg (struct sock *sk, void *msg, int size) { int tocopy=0, copied=0; while (tocopy = (size < sk->tcp->mss) ? size : mss) { if (copied = (free_space (sk->write_queue.prev.space))) { if (copied > tocopy) copied = tocopy; add_data (sk->write_queue.prev, msg, copied); size = size - copied; msg = msg + copied; } else { struct skbuff *skb = alloc_new_skb(); add_data(skb, msg, tocopy); size = size - tocopy; msg = msg + tocopy; entail (sk->write_queue, skb); } } return size; } Phoenix Group Oct-05 INRIA - LaBRI Program Specialization 99 int tcp_mini_sendmsg (struct sock *sk, void *msg, int size) { int tocopy=0, copied=0; while (tocopy = (size < sk->tcp->mss) ? size : mss) { if (copied = (free_space (sk->write_queue.prev.space))) { if (copied > tocopy) copied = tocopy; add_data (sk->write_queue.prev, msg, copied); size = size - copied; msg = msg + copied; } else { struct skbuff *skb = alloc_new_skb(); add_data(skb, msg, tocopy); size = size - tocopy; msg = msg + tocopy; entail (sk->write_queue, skb); } } return size; } Phoenix Group Oct-05 INRIA - LaBRI Program Specialization 100 int tcp_mini_sendmsg (struct sock *sk, void *msg, int size) { int tocopy=0, copied=0; while (tocopy = (size < sk->tcp->mss) ? size : mss) { if (copied = (free_space (sk->write_queue.prev.space))) { if (copied > tocopy) copied = tocopy; add_data (sk->write_queue.prev, msg, copied); size = size - copied; msg = msg + copied; } else { struct skbuff *skb = alloc_new_skb(); add_data(skb, msg, tocopy); size = size - tocopy; msg = msg + tocopy; entail (sk->write_queue, skb); } } return size; } Phoenix Group Oct-05 INRIA - LaBRI Program Specialization size=1400 sk={…} Specialization context: Specialized code: 101 int tcp_mini_sendmsg (void *msg) { struct skbuff *skb = alloc_new_skb(); add_data(skb, msg, 1400); entail (sk->write_queue, skb); return 0; } Phoenix Group Oct-05 INRIA - LaBRI How specialization is introduced Application OS 102 token = do_customize_send(…); for (i=0;i<100000;i++) { customized_send (token, buffer); } Phoenix Group Oct-05 INRIA - LaBRI How specialization is introduced Application OS 103 token = do_customize_send(…); for (i=0;i<100000;i++) { customized_send (token, buffer); } Phoenix Group Oct-05 INRIA - LaBRI How specialization is introduced Application OS 104 token = do_customize_send(…); for (i=0;i<100000;i++) { customized_send (token, buffer); } Phoenix Group Oct-05 INRIA - LaBRI Spec. opportunities in protocol stacks: Eliminating Genericity 105 Eliminating lookups Eliminating option interpretation Eliminating routing decisions Optimizing buffer allocation Optimizing data fragmentation and coalescing Phoenix Group Oct-05 INRIA - LaBRI Eliminating lookups Socket descriptors 106 Application Phoenix Group Oct-05 INRIA - LaBRI Eliminating lookups Socket structures Socket descriptors 107 Protocol layer Kernel Application Phoenix Group Oct-05 INRIA - LaBRI Eliminating lookups Socket structures Protocol layer Kernel Socket i-node Sockets interface Socket descriptors 108 Application Phoenix Group Oct-05 INRIA - LaBRI Eliminating lookups Kernel Application 109 Phoenix Group Oct-05 INRIA - LaBRI Eliminating lookups Kernel sockfd_lookup(sd) Application 110 Phoenix Group Oct-05 INRIA - LaBRI Eliminating socket options BLOCKING NAGLE Application UNICAST 111 Phoenix Group Oct-05 INRIA - LaBRI Eliminating socket options UNICAST? BLOCKING? NAGLE? BLOCKING Kernel NAGLE Application UNICAST 112 Phoenix Group Oct-05 INRIA - LaBRI Eliminating socket options UNICAST? BLOCKING? NAGLE? Kernel sock_sendmsg(…, …, …, flags) BLOCKING NAGLE Application UNICAST 113 Phoenix Group Oct-05 INRIA - LaBRI Eliminating routing decisions NIC driver ip_route_output Kernel TCP/UDP layer System call 114 Phoenix Group Oct-05 INRIA - LaBRI Eliminating routing decisions NIC driver ip_route_output FIB Kernel TCP/UDP layer System call 115 Phoenix Group Oct-05 INRIA - LaBRI Eliminating routing decisions NIC driver ip_route_output Route cache Kernel TCP/UDP layer System call 116 Phoenix Group Oct-05 INRIA - LaBRI Eliminating routing decisions NIC driver ip_route_output Kernel TCP/UDP layer System call connect (int sockfd, struct sockaddr *daddr, int addrlen) 117 Phoenix Group Oct-05 INRIA - LaBRI Optimizing buffer allocation if (in interrupt() && (gfp mask & GFP WAIT)) { gfp mask &= ~GFP WAIT; npages = (dlen + (PAGE SIZE- 1)) >> PAGE SHIFT; skb->truesize += dlen; ((struct skb sharedinfo *) skb->end)->nr frags = npages; for (i = 0; i < npages; i++) { ... } } 118 Phoenix Group Oct-05 Kernel INRIA - LaBRI Optimizing buffer allocation if (in interrupt() && (gfp mask & GFP WAIT)) { gfp mask &= ~GFP WAIT; npages = (dlen + (PAGE SIZE- 1)) >> PAGE SHIFT; skb->truesize += dlen; ((struct skb sharedinfo *) skb->end)->nr frags = npages; for (i = 0; i < npages; i++) { ... } } Kernel setsockopt(…, …, …, SO_FIXADU, &size, …) 119 Phoenix Group Oct-05 INRIA - LaBRI Optimizing coalescing and fragmentation while (seglen > 0) { copy = MSS_now – last_skb_len; if (copy > 0) { if (copy < seglen) copy = seglen; push_into_previous(copy); } else { copy = min(seglen, MSS_now); push_into_current(copy); } seglen -= copy; } Kernel setsockopt(…, …, …, SO_FIXADU, &size, …) 120 Phoenix Group Oct-05 INRIA - LaBRI Specifying the opportunities to the code specializer Original C code: struct sk_buff *sock_alloc_send_pskb( struct sock *sk, unsigned long header len, unsigned long data len, int noblock, int *errcode) { ... } 121 Specialization declarations: Sock alloc_send_pskb:: intern sock_alloc_send_pskb( Spec sock( struct sock) S(*) sk, S( unsigned long ) header len, S( unsigned long ) data len, S( int ) noblock, D( int * ) errcode) { ... }; Phoenix Group Oct-05 INRIA - LaBRI Results: Improvements in Performance and Code Size Execution time decreased by ~25% Code size decreased by a factor of >15 Throughput improvements: – – 122 UDP - PIII: 13% 486: 27% iPAQ: 18% TCP - PIII: 10% 486: 23% iPAQ: 13% Phoenix Group Oct-05 INRIA - LaBRI Specialization Overhead Specialization – – Bottleneck – – 123 Run time for fast specialization Compile time for fast specialized code Execution of specialization Compiler What about performing specialization remotely? Phoenix Group Oct-05 INRIA - LaBRI Conclusion 124 Problem: Need for fast protocol stacks in high speed networks Solution: Program specialization at run time Assessment: Execution time up to 25%, code size up to 15x, throughput up to 20% Phoenix Group Oct-05 INRIA - LaBRI Remote Customization Of Systems Code For Embedded Devices Part III 12 5 INRIA - LaBRI Phoenix Group Oct-05 Problem Statement Embedded systems low on resources OSes generic Overheads (space, time) Need for customization of systems code 126 Phoenix Group Oct-05 INRIA - LaBRI Outline 127 Introduction Code Customization Remote Customization Infrastructure Virtualization of memory Case study: TCP/IP Performance Evaluation Conclusion Phoenix Group Oct-05 INRIA - LaBRI Outline 128 Introduction Remote Customization Infrastructure Virtualization of memory Case study: TCP/IP Performance Evaluation Conclusion Phoenix Group Oct-05 INRIA - LaBRI Dedicated Vs. Generic OSes Generic OSes Dedicated OSes + Deeply customized, compact, fast, well-suited - Lack of support for standards 129 Phoenix Group + Support for standards - Generic, coarse grained abstractions Oct-05 INRIA - LaBRI Industry Trends Percent Embedded Systems Developers Survey, 2002 Source: Evans Data Corp. 130 Phoenix Group Oct-05 INRIA - LaBRI Generic abstractions Coarse grained building blocks if (poll (listen_pfds, n, -1) > 1) { foreach(pfd, listen_pfds) { if (hi_r(pfd->revents)) queue( accept(fd, addr, addr_len)); } } Performance: 3000+ conn/sec. Concrete Operations foreach(sock, my_sockets) { if (sock->sk->accept_queue) { sock->ops->accept(sock, new_sock, O_NONBLOCK); } } Performance: 7000+ conn/sec. Overheads: memory transfers, context switches, sanity checks, data structures 131 Phoenix Group Oct-05 INRIA - LaBRI Generic abstractions Coarse grained building blocks if (poll (listen_pfds, n, -1) > 1) { foreach(pfd, listen_pfds) { if (hi_r(pfd->revents)) queue( accept(fd, addr, addr_len)); } } Performance: 3000+ conn/sec. Concrete Operations foreach(sock, my_sockets) { if (sock->sk->accept_queue) { sock->ops->accept(sock, new_sock, O_NONBLOCK); } } Performance: 7000+ conn/sec. Need for Program Specialization 132 Phoenix Group Oct-05 INRIA - LaBRI Outline 133 Introduction Remote Customization Infrastructure Virtualization of memory Case study: TCP/IP Performance Evaluation Conclusion Phoenix Group Oct-05 INRIA - LaBRI Remote Customization Customized Code Remote customization server 134 Network Phoenix Group Oct-05 INRIA - LaBRI Specialization Opportunity Application for (i=0 ; i < 100000; i++) { send(…, buffer); } OS 135 Phoenix Group Oct-05 INRIA - LaBRI How it’s used Application OS 136 token = do_customize_send(…); for (i=0 ; i < 100000; i++) { customize_send(token, buffer); } Phoenix Group Oct-05 INRIA - LaBRI How it’s used Application OS 137 token = do_customize_send(…); for (i=0 ; i < 100000; i++) { customize_send(token, buffer); } Phoenix Group Oct-05 INRIA - LaBRI How it’s used Application OS 138 token = do_customize_send(…); for (i=0 ; i < 100000; i++) { customize_send(token, buffer); } Phoenix Group Oct-05 INRIA - LaBRI Architecture User space Customizer Compiler Application Runtime Layer Context Manager 139 Kernel Space Code Manager Phoenix Group Context Manager Oct-05 Code Manager INRIA - LaBRI Customization Request Customizer Compiler Runtime Layer Code Manager Context Manager User space Customization Request Application Kernel Space Context Manager Code Manager Application issues customization request 140 Phoenix Group Oct-05 INRIA - LaBRI Context Manager Customizer Compiler Runtime Layer Code Manager Context Manager User space Application syscall=sys_send fd=4; daddr=1044321; flags=32; ... ... Kernel Space Context Manager Code Manager Context manager picks up customization context 141 Phoenix Group Oct-05 INRIA - LaBRI Code Manager Customizer Compiler Runtime Layer Code Manager Context Manager User space Application Kernel Space Context Manager Code Manager Check if we have code for the current context 142 Phoenix Group Oct-05 INRIA - LaBRI Customization Request Customizer fd=4; daddr=1044321; flags=32; addr_len=8; block_size=1483; Compiler (...) Runtime Layer Context Manager User space Application Kernel Space Code Manager Context Manager Code Manager Application issues customization request 143 Phoenix Group Oct-05 INRIA - LaBRI Runtime Layer User space Customizer Compiler Application Runtime Layer Context Manager Kernel Space Code Manager Context Manager Code Manager Context manager invokes runtime layer 144 Phoenix Group Oct-05 INRIA - LaBRI Customizer User space Customizer Compiler Application Runtime Layer Context Manager Kernel Space Code Manager Context Manager Code Manager The program customizer is Tempo 145 Phoenix Group Oct-05 INRIA - LaBRI Compiler User space Customizer Compiler Application Runtime Layer Context Manager Kernel Space Code Manager Context Manager Code Manager The customized code is compiled using a standard compiler 146 Phoenix Group Oct-05 INRIA - LaBRI Code Manager User space Customizer Compiler Application Runtime Layer Context Manager Kernel Space Code Manager Context Manager Code Manager Customized code is sent back 147 Phoenix Group Oct-05 INRIA - LaBRI Customization Token User space Customizer Compiler Application Runtime Layer Context Manager 148 Kernel Space Code Manager Phoenix Group Context Manager Oct-05 Code Manager INRIA - LaBRI Customization Token Customizer Compiler Runtime Layer Code Manager Context Manager User space Application Customization Token (eg., 0 for the first customization) Kernel Space Context Manager Code Manager Application gets back a customization token 149 Phoenix Group Oct-05 INRIA - LaBRI Customization Syscall Customizer Compiler Runtime Layer Code Manager Context Manager User space Per-process syscall table Application Kernel Space Context Manager Code Manager Application uses customization token as an index 150 Phoenix Group Oct-05 INRIA - LaBRI Outline 151 Introduction Code Customization Remote Customization Infrastructure Virtualization of memory Case study: TCP/IP Performance Evaluation Conclusion Phoenix Group Oct-05 INRIA - LaBRI Access to client side memory movl [socket_pointer],%eax Customizer 0xc01f400: 1483 [tcp_mss] 0xc01f363: 0xc01f355 [tp] Runtime Layer 152 1. Run-time layer intercepts dereference, as CPU exception. 2. Run-time layer interprets instruction with values in customization context table. Phoenix Group Oct-05 INRIA - LaBRI Access to client side memory movl [socket_pointer],%eax Customizer 0xc01f400: 1483 [tcp_mss] 0xc01f363: 0xc01f355 [tp] Runtime Layer 153 1. Run-time layer intercepts dereference, as CPU exception. 2. Run-time layer interprets instruction with values in customization context table. 3. Customization-time functions Executed on client Phoenix Group Oct-05 INRIA - LaBRI Outline 154 Introduction Code Customization Remote Customization Infrastructure Virtualization of memory Case study: TCP/IP (already presented) Performance Evaluation Conclusion Phoenix Group Oct-05 INRIA - LaBRI Outline 155 Introduction Code Customization Remote Customization Infrastructure Virtualization of memory Case study: TCP/IP Performance Evaluation (already presented) Conclusion Phoenix Group Oct-05 INRIA - LaBRI Conclusion Problem: – Solution: – – 156 Services in generic OSes are slow and bloated Dynamic program specialization Remote specialization limited resources Assessment: Exec time… -25%, throughput… +20%, code size… -15x Phoenix Group Oct-05 INRIA - LaBRI