Carnegie Mellon MachineLevel Programming IV Data CSCI 370
- Slides: 46
Carnegie Mellon Machine-Level Programming IV: Data CSCI 370: Computer Architecture Slide Attribution: Adopted from CMU 15 -213 Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 1
Carnegie Mellon Today ¢ Arrays § One-dimensional § Multi-dimensional (nested) § Multi-level ¢ Structures § Allocation § Access § Alignment ¢ Floating Point Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 2
Carnegie Mellon Array Allocation ¢ Basic Principle T A[L]; § Array of data type T and length L § Contiguously allocated region of L * sizeof(T) bytes in memory char string[12]; x x + 12 int val[5]; x x + 4 x + 8 x + 12 x + 16 x + 20 double a[3]; x x + 8 x + 16 x + 24 char *p[3]; Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition x + 16 x + 24 3
Carnegie Mellon Array Access ¢ Basic Principle T A[L]; § Array of data type T and length L § Identifier A can be used as a pointer to array element 0: Type T* 1 int val[5]; x ¢ 5 x + 4 2 x + 8 Reference Type Value val[4] val+1 &val[2] val[5] *(val+1) val + i int * int int * 3 x x + 4 x + 8 ? ? 5 x + 4 i Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 1 x + 12 3 x + 16 x + 20 4
Carnegie Mellon Array Example #define ZLEN 5 typedef int zip_dig[ZLEN]; zip_dig cmu = { 1, 5, 2, 1, 3 }; zip_dig mit = { 0, 2, 1, 3, 9 }; zip_dig ucb = { 9, 4, 7, 2, 0 }; 1 zip_dig cmu; 16 20 0 zip_dig mit; 36 56 ¢ 2 24 2 40 9 zip_dig ucb; ¢ 5 28 1 44 4 60 1 32 3 48 7 64 3 9 52 2 68 36 56 0 72 76 Declaration “zip_dig cmu” equivalent to “int cmu[5]” Example arrays were allocated in successive 20 byte blocks § Not guaranteed to happen in general Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 5
Carnegie Mellon Array Accessing Example 1 zip_dig cmu; 16 5 20 2 24 1 3 28 int get_digit (zip_dig z, int digit) { return z[digit]; } IA 32 # %rdi = z # %rsi = digit movl (%rdi, %rsi, 4), %eax # z[digit] 32 n n Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 36 Register %rdi contains starting address of array Register %rsi contains array index Desired digit at %rdi + 4*%rsi Use memory reference (%rdi, %rsi, 4) 6
Carnegie Mellon Array Loop Example void zincr(zip_dig z) { size_t i; for (i = 0; i < ZLEN; i++) z[i]++; } # %rdi = z movl $0, %eax # i = 0 jmp . L 3 # goto middle. L 4: # loop: addl $1, (%rdi, %rax, 4) # z[i]++ addq $1, %rax # i++. L 3: # middle cmpq $4, %rax # i: 4 jbe . L 4 # if <=, goto loop rep; ret Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 7
Carnegie Mellon Multidimensional (Nested) Arrays ¢ Declaration T A[R][C]; § 2 D array of data type T § R rows, C columns § Type T element requires K bytes ¢ Array Size A[0][0] • • • A[0][C-1] • • • A[R-1][0] • • • A[R-1][C-1] § R * C * K bytes ¢ Arrangement § Row-Major Ordering int A[R][C]; A [0] A A • • • [0] [1] [C-1] [0] A • • • [1] [C-1] • • • A A [R-1] • • • [R-1] [0] [C-1] 4*R*C Bytes Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 8
Carnegie Mellon Nested Array Example #define PCOUNT 4 zip_dig pgh[PCOUNT] = {{1, 5, 2, 0, 6}, {1, 5, 2, 1, 3 }, {1, 5, 2, 1, 7 }, {1, 5, 2, 2, 1 }}; zip_dig pgh[4]; 1 5 2 0 6 1 5 2 1 3 1 5 2 1 7 1 5 2 2 1 76 ¢ 96 116 136 156 “zip_dig pgh[4]” equivalent to “int pgh[4][5]” § Variable pgh: array of 4 elements, allocated contiguously § Each element is an array of 5 int’s, allocated contiguously ¢ “Row-Major” ordering of all elements in memory Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 9
Carnegie Mellon Nested Array Row Access ¢ Row Vectors § A[i] is array of C elements § Each element of type T requires K bytes § Starting address A + i * (C * K) int A[R][C]; A[0] A • • • A[i] A [0] [C-1] • • • A [i] [0] • • • A+(i*C*4) Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition A[R-1] A [i] [C-1] • • • A [R-1] [0] • • • A [R-1] [C-1] A+((R-1)*C*4) 10
Carnegie Mellon Nested Array Row Access Code 1 5 2 0 6 1 5 2 1 3 1 5 2 1 7 1 5 2 2 1 int *get_pgh_zip(int index) { return pgh[index]; } pgh # %rdi = index leaq (%rdi, 4), %rax # 5 * index leaq pgh(, %rax, 4), %rax # pgh + (20 * index) ¢ Row Vector § pgh[index] is array of 5 int’s § Starting address pgh+20*index ¢ Machine Code § Computes and returns address § Compute as pgh + 4*(index+4*index) Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 11
Carnegie Mellon Nested Array Element Access ¢ Array Elements § A[i][j] is element of type T, which requires K bytes § Address A + i * (C * K) + j * K = A + (i * C + j)* K int A[R][C]; A[0] A • • • A[i] A [0] [C-1] • • • A [i] • • [j] A[R-1] • • • A+(i*C*4) A [R-1] [0] • • • A [R-1] [C-1] A+((R-1)*C*4) A+(i*C*4)+(j*4) Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 12
Carnegie Mellon Nested Array Element Access Code 1 5 2 0 6 1 5 2 1 3 1 5 2 1 7 1 5 2 2 1 pgh int get_pgh_digit (int index, int dig) { return pgh[index][dig]; } leaq addl movl ¢ (%rdi, 4), %rax, %rsi pgh(, %rsi, 4), %eax # 5*index+dig # M[pgh + 4*(5*index+dig)] Array Elements § pgh[index][dig] is int § Address: pgh + 20*index + 4*dig § = pgh + 4*(5*index + dig) Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 13
Carnegie Mellon Multi-Level Array Example ¢ zip_dig cmu = { 1, 5, 2, 1, 3 }; zip_dig mit = { 0, 2, 1, 3, 9 }; zip_dig ucb = { 9, 4, 7, 2, 0 }; ¢ #define UCOUNT 3 int *univ[UCOUNT] = {mit, cmu, ucb}; cmu univ 160 36 168 16 176 56 mit 1 16 5 20 0 ucb 36 2 9 Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 2 24 40 56 ¢ 1 28 1 44 4 60 Variable univ denotes array of 3 elements Each element is a pointer § 8 bytes Each pointer points to array of int’s 32 3 48 7 64 3 9 52 2 68 36 56 0 72 76 14
Carnegie Mellon Element Access in Multi-Level Array int get_univ_digit (size_t index, size_t digit) { return univ[index][digit]; } salq $2, %rsi # 4*digit addq univ(, %rdi, 8), %rsi # p = univ[index] + 4*digit movl (%rsi), %eax # return *p ret ¢ Computation § Element access Mem[univ+8*index]+4*digit] § Must do two memory reads First get pointer to row array § Then access element within array § Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 15
Carnegie Mellon Array Element Accesses Multi-level array Nested array int get_pgh_digit int get_univ_digit (size_t index, size_t digit) { { return pgh[index][digit]; return univ[index][digit]; } } Accesses looks similar in C, but address computations very different: Mem[pgh+20*index+4*digit] Mem[univ+8*index]+4*digit] Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 16
Carnegie Mellon N X N Matrix Code ¢ Fixed dimensions § Know value of N at compile time ¢ Variable dimensions, explicit indexing § Traditional way to implement dynamic arrays ¢ Variable dimensions, implicit indexing § Now supported by gcc #define N 16 typedef int fix_matrix[N][N]; /* Get element a[i][j] */ int fix_ele(fix_matrix a, size_t i, size_t j) { return a[i][j]; } #define IDX(n, i, j) ((i)*(n)+(j)) /* Get element a[i][j] */ int vec_ele(size_t n, int *a, size_t i, size_t j) { return a[IDX(n, i, j)]; } /* Get element a[i][j] */ int var_ele(size_t n, int a[n][n], size_t i, size_t j) { return a[i][j]; } Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 17
Carnegie Mellon 16 X 16 Matrix Access ¢ Array Elements § Address A + i * (C * K) + j * K § C = 16, K = 4 /* Get element a[i][j] */ int fix_ele(fix_matrix a, size_t i, size_t j) { return a[i][j]; } # a in %rdi, i in %rsi, j in %rdx salq $6, %rsi # 64*i addq %rsi, %rdi # a + 64*i movl (%rdi, %rdx, 4), %eax # M[a + 64*i + 4*j] ret Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 18
Carnegie Mellon n X n Matrix Access ¢ Array Elements § Address A + i * (C * K) + j * K § C = n, K = 4 § Must perform integer multiplication /* Get element a[i][j] */ int var_ele(size_t n, int a[n][n], size_t i, size_t j) { return a[i][j]; } # n in %rdi, a in %rsi, i in %rdx, j in %rcx imulq %rdx, %rdi # n*i leaq (%rsi, %rdi, 4), %rax # a + 4*n*i movl (%rax, %rcx, 4), %eax # a + 4*n*i + 4*j ret Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 19
Carnegie Mellon Today ¢ Arrays § One-dimensional § Multi-dimensional (nested) § Multi-level ¢ Structures § Allocation § Access § Alignment ¢ Floating Point Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 20
Carnegie Mellon Structure Representation struct rec { int a[4]; size_t i; struct rec *next; }; ¢ r a 0 i 16 next 24 32 Structure represented as block of memory § Big enough to hold all of the fields ¢ Fields ordered according to declaration § Even if another ordering could yield a more compact representation ¢ Compiler determines overall size + positions of fields § Machine-level program has no understanding of the structures in the source code Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 21
Carnegie Mellon Generating Pointer to Structure Member struct rec { int a[4]; size_t i; struct rec *next; }; ¢ Generating Pointer to Array Element § Offset of each structure member determined at compile time § Compute as r + 4*idx r r+4*idx a 0 i 16 next 24 32 int *get_ap (struct rec *r, size_t idx) { return &r->a[idx]; } # r in %rdi, idx in %rsi leaq (%rdi, %rsi, 4), %rax ret Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 22
Carnegie Mellon Following Linked List ¢ C Code void set_val (struct rec *r, int val) { while (r) { int i = r->i; r->a[i] = val; r = r->next; } } r struct rec { int a[4]; int i; struct rec *next; }; a i 16 0 next 24 32 Element i Register Value %rdi r %rsi val . L 11: # loop: movslq 16(%rdi), %rax # i = M[r+16] movl %esi, (%rdi, %rax, 4) # M[r+4*i] = val movq 24(%rdi), %rdi # r = M[r+24] testq %rdi, %rdi # Test r jne . L 11 # if !=0 goto loop Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 23
Carnegie Mellon Structures & Alignment Unaligned Data ¢ c i[0] p p+1 i[1] p+5 v p+9 p+17 struct S 1 { char c; int i[2]; double v; } *p; Aligned Data ¢ § Primitive data type requires K bytes § Address must be multiple of K c p+0 3 bytes i[0] p+4 i[1] p+8 Multiple of 4 Multiple of 8 Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 4 bytes p+16 v p+24 Multiple of 8 24
Carnegie Mellon Alignment Principles ¢ Aligned Data § Primitive data type requires K bytes § Address must be multiple of K § Required on some machines; advised on x 86 -64 ¢ Motivation for Aligning Data § Memory accessed by (aligned) chunks of 4 or 8 bytes (system dependent) § Inefficient to load or store datum that spans quad word boundaries § Virtual memory trickier when datum spans 2 pages ¢ Compiler § Inserts gaps in structure to ensure correct alignment of fields Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 25
Carnegie Mellon Specific Cases of Alignment (x 86 -64) ¢ 1 byte: char, … § no restrictions on address ¢ 2 bytes: short, … § lowest 1 bit of address must be 02 ¢ 4 bytes: int, float, … § lowest 2 bits of address must be 002 ¢ 8 bytes: double, long, char *, … § lowest 3 bits of address must be 0002 ¢ 16 bytes: long double (GCC on Linux) § lowest 4 bits of address must be 00002 Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 26
Carnegie Mellon Satisfying Alignment with Structures ¢ Within structure: § Must satisfy each element’s alignment requirement ¢ Overall structure placement § Each structure has alignment requirement K struct S 1 { char c; int i[2]; double v; } *p; K = Largest alignment of any element § Initial address & structure length must be multiples of K § ¢ Example: § K = 8, due to double element c p+0 3 bytes i[0] p+4 i[1] p+8 Multiple of 4 Multiple of 8 Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 4 bytes p+16 v p+24 Multiple of 8 27
Carnegie Mellon Meeting Overall Alignment Requirement ¢ ¢ For largest alignment requirement K Overall structure must be multiple of K v p+0 i[0] p+8 i[1] struct S 2 { double v; int i[2]; char c; } *p; c 7 bytes p+16 p+24 Multiple of K=8 Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 28
Carnegie Mellon Arrays of Structures ¢ ¢ struct S 2 { double v; int i[2]; char c; } a[10]; Overall structure length multiple of K Satisfy alignment requirement for every element a[0] a+0 a[1] a+24 v a+24 i[0] a+32 Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition • • • a[2] a+48 i[1] a+72 c a+40 7 bytes a+48 29
Carnegie Mellon Accessing Array Elements Compute array offset 12*idx ¢ § sizeof(S 3), including alignment spacers struct S 3 { short i; float v; short j; } a[10]; Element j is at offset 8 within structure Assembler gives offset a+8 ¢ ¢ § Resolved during linking • • • a[0] a+0 a+12 i a+12*idx short get_j(int idx) { return a[idx]. j; } a[idx] • • • a+12*idx 2 bytes v j 2 bytes a+12*idx+8 # %rdi = idx leaq (%rdi, 2), %rax # 3*idx movzwl a+8(, %rax, 4), %eax Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 30
Carnegie Mellon Saving Space ¢ Put large data types first struct S 5 { int i; char c; char d; } *p; struct S 4 { char c; int i; char d; } *p; ¢ Effect (K=4) c i 3 bytes i c d d 3 bytes 2 bytes Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 31
Carnegie Mellon Today ¢ Arrays § One-dimensional § Multi-dimensional (nested) § Multi-level ¢ Structures § Allocation § Access § Alignment ¢ Floating Point Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 32
Carnegie Mellon Background ¢ History § x 87 FP Legacy, very ugly § SSE FP § Supported by all Intel/AMD machines § Special case use of vector instructions § AVX FP § Newest version (supported on all modern x 86 architectures) § Similar to SSE § Documented in book § Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 33
Programming with SSE 3 Carnegie Mellon XMM Registers n 16 total, each 16 bytes n 16 single-byte integers n 8 16 -bit integers n 4 32 -bit integers n 4 single-precision floats n 2 double-precision floats n 1 single-precision float n 1 double-precision float Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 34
Carnegie Mellon Scalar & SIMD Operations n Scalar Operations: Single Precision addss %xmm 0, %xmm 1 %xmm 0 + %xmm 1 n SIMD Operations: Single Precision addps %xmm 0, %xmm 1 %xmm 0 + + %xmm 1 n Scalar Operations: Double Precision addsd %xmm 0, %xmm 1 %xmm 0 + Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition %xmm 1 35
Carnegie Mellon FP Basics ¢ ¢ ¢ Arguments passed in %xmm 0, %xmm 1, . . . Result returned in %xmm 0 All XMM registers caller-saved float fadd(float x, float y) { return x + y; } double dadd(double x, double y) { return x + y; } # x in %xmm 0, y in %xmm 1 addss %xmm 1, %xmm 0 ret # x in %xmm 0, y in %xmm 1 addsd %xmm 1, %xmm 0 ret Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 36
Carnegie Mellon FP Memory Referencing ¢ ¢ ¢ Integer (and pointer) arguments passed in regular registers FP values passed in XMM registers Different mov instructions to move between XMM registers, and between memory and XMM registers double dincr(double *p, double v) { double x = *p; *p = x + v; return x; } # p in %rdi, v in %xmm 0 movapd %xmm 0, %xmm 1 # Copy v movsd (%rdi), %xmm 0 # x = *p addsd %xmm 0, %xmm 1 # t = x + v movsd %xmm 1, (%rdi) # *p = t ret Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 37
Carnegie Mellon Other Aspects of FP Code ¢ Lots of instructions § Different operations, different formats, . . . ¢ Floating-point comparisons § Instructions ucomiss and ucomisd § Set condition codes CF, ZF, and PF ¢ Using constant values § Set XMM 0 register to 0 with instruction xorpd %xmm 0, %xmm 0 § Others loaded from memory Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 38
Carnegie Mellon Summary ¢ Arrays § Elements packed into contiguous region of memory § Use index arithmetic to locate individual elements ¢ Structures § Elements packed into single region of memory § Access using offsets determined by compiler § Possible require internal and external padding to ensure alignment ¢ Combinations § Can nest structure and array code arbitrarily ¢ Floating Point § Data held and operated on in XMM registers Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 39
Carnegie Mellon Understanding Pointers & Arrays #1 Decl An Cmp Bad *An Size Cmp Bad Size int A 1[3] int *A 2 ¢ ¢ ¢ Cmp: Compiles (Y/N) Bad: Possible bad pointer reference (Y/N) Size: Value returned by sizeof Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 40
Carnegie Mellon Understanding Pointers & Arrays #1 Decl An *An Cmp Bad Size int A 1[3] Y N 12 Y N 4 int *A 2 Y N 8 Y Y 4 A 1 A 2 ¢ ¢ ¢ Allocated pointer Unallocated pointer Allocated int Unallocated int Cmp: Compiles (Y/N) Bad: Possible bad pointer reference (Y/N) Size: Value returned by sizeof Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 41
Carnegie Mellon Understanding Pointers & Arrays #2 Decl An Cmp Bad *An Size Cmp Bad **An Size Cmp Bad Size int A 1[3] int *A 2[3] int (*A 3)[3] int (*A 4[3]) ¢ ¢ ¢ Cmp: Compiles (Y/N) Bad: Possible bad pointer reference (Y/N) Size: Value returned by sizeof Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 42
Carnegie Mellon Understanding Pointers & Arrays #2 Decl An **An Cmp Bad Size int A 1[3] Y N 12 Y N 4 N - - int *A 2[3] Y N 24 Y N 8 Y Y 4 int (*A 3)[3] Y N 8 Y Y 12 Y Y 4 int (*A 4[3]) Y N 24 Y N 8 Y Y 4 A 1 A 2/A 4 A 3 Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition Allocated pointer Unallocated pointer Allocated int Unallocated int 43
Carnegie Mellon Understanding Pointers & Arrays #3 Decl An *An Cmp Bad Size Cmp Bad **An Size Cmp Bad Size int A 1[3][5] int *A 2[3][5] int (*A 3)[3][5] int *(A 4[3][5]) int (*A 5[3])[5] ¢ ¢ ¢ Cmp: Compiles (Y/N) Bad: Possible bad pointer reference (Y/N) Size: Value returned by sizeof Decl ***An Cmp Bad Size int A 1[3][5] int *A 2[3][5] int (*A 3)[3][5] int *(A 4[3][5]) int (*A 5[3])[5] Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 44
Carnegie Mellon Allocated pointer to unallocated int Unallocated pointer Allocated int Unallocated int Declaration int A 1[3][5] int *A 2[3][5] int (*A 3)[3][5] int *(A 4[3][5]) int (*A 5[3])[5] A 1 A 2/A 4 A 3 A 5 Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 45
Carnegie Mellon Understanding Pointers & Arrays #3 Decl An **An Cmp Bad Size int A 1[3][5] Y N 60 Y N 20 Y N 4 int *A 2[3][5] Y N 120 Y N 40 Y N 8 int (*A 3)[3][5] Y N 8 Y Y 60 Y Y 20 int *(A 4[3][5]) Y N 120 Y N 40 Y N 8 int (*A 5[3])[5] Y N 24 Y N 8 Y Y 20 ¢ ¢ ¢ Cmp: Compiles (Y/N) Bad: Possible bad pointer reference (Y/N) Size: Value returned by sizeof Decl ***An Cmp Bad Size int A 1[3][5] N - - int *A 2[3][5] Y Y 4 int (*A 3)[3][5] Y Y 4 int *(A 4[3][5]) Y Y 4 int (*A 5[3])[5] Y Y 4 Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition 46
- Comp bio cmu
- Carnegie mellon interdisciplinary
- Carnegie mellon software architecture
- Bomb lab solutions
- Carnegie mellon software architecture
- Cmu citi training
- Cmu mism
- Randy pausch time management slides
- National robotics initiative
- Carnegie mellon
- Carnegie mellon
- Carnegie mellon vpn
- Carnegie mellon
- Carnegie mellon
- Carnegie mellon
- Frax
- Carnegie mellon fat letter
- 15-513 cmu
- Assembly bomb lab
- Instruction format of ibm 360 in system programming
- Mellon serbia iskustva
- Carneigh mellon
- Christina mellon
- Bny mellon health savings account
- Zebulun krahn
- Water mellon
- Mellon elf
- Mellon elf
- Mellon elf
- Hero br
- The rise
- Was andrew carnegie bad
- Modelo incrementalista
- Andrew carnegie vertical integration
- Andrew carnegie vertical integration
- Andrew carnegie vertical integration
- Horizontal integration rockefeller
- Carnegie and rockefeller venn diagram
- Dale carnegie conversation stack
- Carnegie learning
- Carnegie hall acadia
- Carnegie
- Jack carnegie
- Carnegie
- Spend bll gates money
- Carnegie robotics llc
- Jp morgan vertical integration