centralized performance resources
This commit is contained in:
commit
50b15a1522
63 changed files with 328466 additions and 0 deletions
BIN
ocw/1/assignment.pdf
Normal file
BIN
ocw/1/assignment.pdf
Normal file
Binary file not shown.
31
ocw/1/c-primer/Makefile
Normal file
31
ocw/1/c-primer/Makefile
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
CC := clang
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS := -Wall -O0 -g
|
||||
else
|
||||
CFLAGS := -Wall -O1 -DNDEBUG
|
||||
endif
|
||||
|
||||
LDFLAGS := -lrt -flto -fuse-ld=gold
|
||||
|
||||
all: sizes pointer swap
|
||||
|
||||
sizes.o: sizes.c
|
||||
$(CC) $(CFLAGS) -c sizes.c
|
||||
|
||||
sizes: sizes.o
|
||||
$(CC) -o sizes sizes.o $(LDFLAGS)
|
||||
|
||||
pointer.o: pointer.c
|
||||
$(CC) $(CFLAGS) -c pointer.c
|
||||
|
||||
pointer: pointer.o
|
||||
$(CC) -o pointer pointer.o $(LDFLAGS)
|
||||
|
||||
swap.o: swap.c
|
||||
$(CC) $(CFLAGS) -c swap.c
|
||||
|
||||
swap: swap.o
|
||||
$(CC) -o swap swap.o $(LDFLAGS)
|
||||
clean:
|
||||
rm -f sizes pointer swap *.o *.gcda *.gcno *.gcov perf.data */perf.data cachegrind.out.*
|
||||
47
ocw/1/c-primer/pointer.c
Normal file
47
ocw/1/c-primer/pointer.c
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright (c) 2012 MIT License by 6.172 Staff
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int main(int argc, char * argv[]) { // What is the type of argv?
|
||||
int i = 5;
|
||||
// The & operator here gets the address of i and stores it into pi
|
||||
int * pi = &i;
|
||||
// The * operator here dereferences pi and stores the value -- 5 --
|
||||
// into j.
|
||||
int j = *pi;
|
||||
|
||||
char c[] = "6.172";
|
||||
char * pc = c; // Valid assignment: c acts like a pointer to c[0] here.
|
||||
char d = *pc;
|
||||
printf("char d = %c\n", d); // What does this print?
|
||||
|
||||
// compound types are read right to left in C.
|
||||
// pcp is a pointer to a pointer to a char, meaning that
|
||||
// pcp stores the address of a char pointer.
|
||||
char ** pcp;
|
||||
pcp = argv; // Why is this assignment valid?
|
||||
|
||||
const char * pcc = c; // pcc is a pointer to char constant
|
||||
char const * pcc2 = c; // What is the type of pcc2?
|
||||
|
||||
// For each of the following, why is the assignment:
|
||||
*pcc = '7'; // invalid?
|
||||
pcc = *pcp; // valid?
|
||||
pcc = argv[0]; // valid?
|
||||
|
||||
char * const cp = c; // cp is a const pointer to char
|
||||
// For each of the following, why is the assignment:
|
||||
cp = *pcp; // invalid?
|
||||
cp = *argv; // invalid?
|
||||
*cp = '!'; // valid?
|
||||
|
||||
const char * const cpc = c; // cpc is a const pointer to char const
|
||||
// For each of the following, why is the assignment:
|
||||
cpc = *pcp; // invalid?
|
||||
cpc = argv[0]; // invalid?
|
||||
*cpc = '@'; // invalid?
|
||||
|
||||
return 0;
|
||||
}
|
||||
21
ocw/1/c-primer/preprocess.c
Normal file
21
ocw/1/c-primer/preprocess.c
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright (c) 2012 MIT License by 6.172 Staff
|
||||
|
||||
// All occurences of ONE will be replaced by 1.
|
||||
#define ONE 1
|
||||
|
||||
// Macros can also behave similar to inline functions.
|
||||
// Note that parentheses around arguments are required to preserve order of
|
||||
// operations. Otherwise, you can introduce bugs when substitution happens
|
||||
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
int c = ONE, d = ONE + 5;
|
||||
int e = MIN(c, d);
|
||||
|
||||
#ifndef NDEBUG
|
||||
// This code will be compiled only when
|
||||
// the macro NDEBUG is not defined.
|
||||
// Recall that if clang is passed -DNDEBUG on the command line,
|
||||
// then NDEBUG will be defined.
|
||||
if (something) {}
|
||||
#endif
|
||||
14
ocw/1/c-primer/sizes.c
Normal file
14
ocw/1/c-primer/sizes.c
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright (c) 2012 MIT License by 6.172 Staff
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void subprocedure(int x, int y) {
|
||||
int z = x + y;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int x = 3, y = 5;
|
||||
subprocedure(x, y);
|
||||
}
|
||||
476
ocw/1/c-primer/sizes.s
Normal file
476
ocw/1/c-primer/sizes.s
Normal file
|
|
@ -0,0 +1,476 @@
|
|||
.file "sizes.c"
|
||||
.text
|
||||
.Ltext0:
|
||||
.file 0 "/home/frozen/dev/performance-engineering-ocw/1/c-primer" "sizes.c"
|
||||
.section .rodata
|
||||
.LC0:
|
||||
.string "size of int : %zu bytes \n"
|
||||
.LC1:
|
||||
.string "size of you : %zu bytes \n"
|
||||
.text
|
||||
.globl main
|
||||
.type main, @function
|
||||
main:
|
||||
.LFB6:
|
||||
.file 1 "sizes.c"
|
||||
.loc 1 9 12
|
||||
.cfi_startproc
|
||||
pushq %rbp
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_offset 6, -16
|
||||
movq %rsp, %rbp
|
||||
.cfi_def_cfa_register 6
|
||||
subq $48, %rsp
|
||||
.loc 1 9 12
|
||||
movq %fs:40, %rax
|
||||
movq %rax, -8(%rbp)
|
||||
xorl %eax, %eax
|
||||
.loc 1 18 3
|
||||
leaq .LC0(%rip), %rax
|
||||
movl $4, %esi
|
||||
movq %rax, %rdi
|
||||
movl $0, %eax
|
||||
call printf@PLT
|
||||
.loc 1 35 10
|
||||
movl $12345, -40(%rbp)
|
||||
.loc 1 36 12
|
||||
movl $4, -36(%rbp)
|
||||
.loc 1 43 3
|
||||
leaq .LC1(%rip), %rax
|
||||
movl $8, %esi
|
||||
movq %rax, %rdi
|
||||
movl $0, %eax
|
||||
call printf@PLT
|
||||
.loc 1 45 10
|
||||
movl $0, %eax
|
||||
.loc 1 46 1
|
||||
movq -8(%rbp), %rdx
|
||||
subq %fs:40, %rdx
|
||||
je .L3
|
||||
call __stack_chk_fail@PLT
|
||||
.L3:
|
||||
leave
|
||||
.cfi_def_cfa 7, 8
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE6:
|
||||
.size main, .-main
|
||||
.Letext0:
|
||||
.file 2 "/usr/include/stdio.h"
|
||||
.section .debug_info,"",@progbits
|
||||
.Ldebug_info0:
|
||||
.long 0x118
|
||||
.value 0x5
|
||||
.byte 0x1
|
||||
.byte 0x8
|
||||
.long .Ldebug_abbrev0
|
||||
.uleb128 0x3
|
||||
.long .LASF13
|
||||
.byte 0x1d
|
||||
.byte 0x3
|
||||
.long 0x31647
|
||||
.long .LASF0
|
||||
.long .LASF1
|
||||
.quad .Ltext0
|
||||
.quad .Letext0-.Ltext0
|
||||
.long .Ldebug_line0
|
||||
.uleb128 0x1
|
||||
.byte 0x8
|
||||
.byte 0x7
|
||||
.long .LASF2
|
||||
.uleb128 0x1
|
||||
.byte 0x4
|
||||
.byte 0x7
|
||||
.long .LASF3
|
||||
.uleb128 0x1
|
||||
.byte 0x1
|
||||
.byte 0x8
|
||||
.long .LASF4
|
||||
.uleb128 0x1
|
||||
.byte 0x2
|
||||
.byte 0x7
|
||||
.long .LASF5
|
||||
.uleb128 0x1
|
||||
.byte 0x1
|
||||
.byte 0x6
|
||||
.long .LASF6
|
||||
.uleb128 0x1
|
||||
.byte 0x2
|
||||
.byte 0x5
|
||||
.long .LASF7
|
||||
.uleb128 0x4
|
||||
.byte 0x4
|
||||
.byte 0x5
|
||||
.string "int"
|
||||
.uleb128 0x1
|
||||
.byte 0x8
|
||||
.byte 0x5
|
||||
.long .LASF8
|
||||
.uleb128 0x1
|
||||
.byte 0x1
|
||||
.byte 0x6
|
||||
.long .LASF9
|
||||
.uleb128 0x5
|
||||
.long 0x6b
|
||||
.uleb128 0x6
|
||||
.byte 0x8
|
||||
.long 0x72
|
||||
.uleb128 0x1
|
||||
.byte 0x8
|
||||
.byte 0x5
|
||||
.long .LASF10
|
||||
.uleb128 0x1
|
||||
.byte 0x8
|
||||
.byte 0x7
|
||||
.long .LASF11
|
||||
.uleb128 0x7
|
||||
.long .LASF14
|
||||
.byte 0x2
|
||||
.value 0x16b
|
||||
.byte 0xc
|
||||
.long 0x5d
|
||||
.long 0xa3
|
||||
.uleb128 0x8
|
||||
.long 0x77
|
||||
.uleb128 0x9
|
||||
.byte 0
|
||||
.uleb128 0xa
|
||||
.long .LASF15
|
||||
.byte 0x1
|
||||
.byte 0x9
|
||||
.byte 0x5
|
||||
.long 0x5d
|
||||
.quad .LFB6
|
||||
.quad .LFE6-.LFB6
|
||||
.uleb128 0x1
|
||||
.byte 0x9c
|
||||
.long 0x10f
|
||||
.uleb128 0xb
|
||||
.byte 0x8
|
||||
.byte 0x1
|
||||
.byte 0x1d
|
||||
.byte 0xb
|
||||
.long 0xe8
|
||||
.uleb128 0xc
|
||||
.string "id"
|
||||
.byte 0x1
|
||||
.byte 0x1e
|
||||
.byte 0x9
|
||||
.long 0x5d
|
||||
.byte 0
|
||||
.uleb128 0xd
|
||||
.long .LASF12
|
||||
.byte 0x1
|
||||
.byte 0x1f
|
||||
.byte 0x9
|
||||
.long 0x5d
|
||||
.byte 0x4
|
||||
.byte 0
|
||||
.uleb128 0xe
|
||||
.long .LASF16
|
||||
.byte 0x1
|
||||
.byte 0x20
|
||||
.byte 0x5
|
||||
.long 0xc5
|
||||
.uleb128 0x2
|
||||
.string "you"
|
||||
.byte 0x22
|
||||
.byte 0xb
|
||||
.long 0xe8
|
||||
.uleb128 0x2
|
||||
.byte 0x91
|
||||
.sleb128 -56
|
||||
.uleb128 0x2
|
||||
.string "x"
|
||||
.byte 0x28
|
||||
.byte 0x7
|
||||
.long 0x10f
|
||||
.uleb128 0x2
|
||||
.byte 0x91
|
||||
.sleb128 -48
|
||||
.byte 0
|
||||
.uleb128 0xf
|
||||
.long 0x5d
|
||||
.uleb128 0x10
|
||||
.long 0x33
|
||||
.byte 0x4
|
||||
.byte 0
|
||||
.byte 0
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.Ldebug_abbrev0:
|
||||
.uleb128 0x1
|
||||
.uleb128 0x24
|
||||
.byte 0
|
||||
.uleb128 0xb
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3e
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3
|
||||
.uleb128 0xe
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x2
|
||||
.uleb128 0x34
|
||||
.byte 0
|
||||
.uleb128 0x3
|
||||
.uleb128 0x8
|
||||
.uleb128 0x3a
|
||||
.uleb128 0x21
|
||||
.sleb128 1
|
||||
.uleb128 0x3b
|
||||
.uleb128 0xb
|
||||
.uleb128 0x39
|
||||
.uleb128 0xb
|
||||
.uleb128 0x49
|
||||
.uleb128 0x13
|
||||
.uleb128 0x2
|
||||
.uleb128 0x18
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x3
|
||||
.uleb128 0x11
|
||||
.byte 0x1
|
||||
.uleb128 0x25
|
||||
.uleb128 0xe
|
||||
.uleb128 0x13
|
||||
.uleb128 0xb
|
||||
.uleb128 0x90
|
||||
.uleb128 0xb
|
||||
.uleb128 0x91
|
||||
.uleb128 0x6
|
||||
.uleb128 0x3
|
||||
.uleb128 0x1f
|
||||
.uleb128 0x1b
|
||||
.uleb128 0x1f
|
||||
.uleb128 0x11
|
||||
.uleb128 0x1
|
||||
.uleb128 0x12
|
||||
.uleb128 0x7
|
||||
.uleb128 0x10
|
||||
.uleb128 0x17
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x4
|
||||
.uleb128 0x24
|
||||
.byte 0
|
||||
.uleb128 0xb
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3e
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3
|
||||
.uleb128 0x8
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x5
|
||||
.uleb128 0x26
|
||||
.byte 0
|
||||
.uleb128 0x49
|
||||
.uleb128 0x13
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x6
|
||||
.uleb128 0xf
|
||||
.byte 0
|
||||
.uleb128 0xb
|
||||
.uleb128 0xb
|
||||
.uleb128 0x49
|
||||
.uleb128 0x13
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x7
|
||||
.uleb128 0x2e
|
||||
.byte 0x1
|
||||
.uleb128 0x3f
|
||||
.uleb128 0x19
|
||||
.uleb128 0x3
|
||||
.uleb128 0xe
|
||||
.uleb128 0x3a
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3b
|
||||
.uleb128 0x5
|
||||
.uleb128 0x39
|
||||
.uleb128 0xb
|
||||
.uleb128 0x27
|
||||
.uleb128 0x19
|
||||
.uleb128 0x49
|
||||
.uleb128 0x13
|
||||
.uleb128 0x3c
|
||||
.uleb128 0x19
|
||||
.uleb128 0x1
|
||||
.uleb128 0x13
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x8
|
||||
.uleb128 0x5
|
||||
.byte 0
|
||||
.uleb128 0x49
|
||||
.uleb128 0x13
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x9
|
||||
.uleb128 0x18
|
||||
.byte 0
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0xa
|
||||
.uleb128 0x2e
|
||||
.byte 0x1
|
||||
.uleb128 0x3f
|
||||
.uleb128 0x19
|
||||
.uleb128 0x3
|
||||
.uleb128 0xe
|
||||
.uleb128 0x3a
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3b
|
||||
.uleb128 0xb
|
||||
.uleb128 0x39
|
||||
.uleb128 0xb
|
||||
.uleb128 0x27
|
||||
.uleb128 0x19
|
||||
.uleb128 0x49
|
||||
.uleb128 0x13
|
||||
.uleb128 0x11
|
||||
.uleb128 0x1
|
||||
.uleb128 0x12
|
||||
.uleb128 0x7
|
||||
.uleb128 0x40
|
||||
.uleb128 0x18
|
||||
.uleb128 0x7c
|
||||
.uleb128 0x19
|
||||
.uleb128 0x1
|
||||
.uleb128 0x13
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0xb
|
||||
.uleb128 0x13
|
||||
.byte 0x1
|
||||
.uleb128 0xb
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3a
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3b
|
||||
.uleb128 0xb
|
||||
.uleb128 0x39
|
||||
.uleb128 0xb
|
||||
.uleb128 0x1
|
||||
.uleb128 0x13
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0xc
|
||||
.uleb128 0xd
|
||||
.byte 0
|
||||
.uleb128 0x3
|
||||
.uleb128 0x8
|
||||
.uleb128 0x3a
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3b
|
||||
.uleb128 0xb
|
||||
.uleb128 0x39
|
||||
.uleb128 0xb
|
||||
.uleb128 0x49
|
||||
.uleb128 0x13
|
||||
.uleb128 0x38
|
||||
.uleb128 0xb
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0xd
|
||||
.uleb128 0xd
|
||||
.byte 0
|
||||
.uleb128 0x3
|
||||
.uleb128 0xe
|
||||
.uleb128 0x3a
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3b
|
||||
.uleb128 0xb
|
||||
.uleb128 0x39
|
||||
.uleb128 0xb
|
||||
.uleb128 0x49
|
||||
.uleb128 0x13
|
||||
.uleb128 0x38
|
||||
.uleb128 0xb
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0xe
|
||||
.uleb128 0x16
|
||||
.byte 0
|
||||
.uleb128 0x3
|
||||
.uleb128 0xe
|
||||
.uleb128 0x3a
|
||||
.uleb128 0xb
|
||||
.uleb128 0x3b
|
||||
.uleb128 0xb
|
||||
.uleb128 0x39
|
||||
.uleb128 0xb
|
||||
.uleb128 0x49
|
||||
.uleb128 0x13
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0xf
|
||||
.uleb128 0x1
|
||||
.byte 0x1
|
||||
.uleb128 0x49
|
||||
.uleb128 0x13
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x10
|
||||
.uleb128 0x21
|
||||
.byte 0
|
||||
.uleb128 0x49
|
||||
.uleb128 0x13
|
||||
.uleb128 0x2f
|
||||
.uleb128 0xb
|
||||
.byte 0
|
||||
.byte 0
|
||||
.byte 0
|
||||
.section .debug_aranges,"",@progbits
|
||||
.long 0x2c
|
||||
.value 0x2
|
||||
.long .Ldebug_info0
|
||||
.byte 0x8
|
||||
.byte 0
|
||||
.value 0
|
||||
.value 0
|
||||
.quad .Ltext0
|
||||
.quad .Letext0-.Ltext0
|
||||
.quad 0
|
||||
.quad 0
|
||||
.section .debug_line,"",@progbits
|
||||
.Ldebug_line0:
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.LASF10:
|
||||
.string "long long int"
|
||||
.LASF3:
|
||||
.string "unsigned int"
|
||||
.LASF15:
|
||||
.string "main"
|
||||
.LASF13:
|
||||
.string "GNU C23 15.1.1 20250425 -mtune=generic -march=x86-64 -g -O0"
|
||||
.LASF2:
|
||||
.string "long unsigned int"
|
||||
.LASF11:
|
||||
.string "long long unsigned int"
|
||||
.LASF4:
|
||||
.string "unsigned char"
|
||||
.LASF9:
|
||||
.string "char"
|
||||
.LASF8:
|
||||
.string "long int"
|
||||
.LASF16:
|
||||
.string "student"
|
||||
.LASF12:
|
||||
.string "year"
|
||||
.LASF5:
|
||||
.string "short unsigned int"
|
||||
.LASF14:
|
||||
.string "printf"
|
||||
.LASF7:
|
||||
.string "short int"
|
||||
.LASF6:
|
||||
.string "signed char"
|
||||
.section .debug_line_str,"MS",@progbits,1
|
||||
.LASF0:
|
||||
.string "sizes.c"
|
||||
.LASF1:
|
||||
.string "/home/frozen/dev/performance-engineering-ocw/1/c-primer"
|
||||
.ident "GCC: (GNU) 15.1.1 20250425"
|
||||
.section .note.GNU-stack,"",@progbits
|
||||
21
ocw/1/c-primer/swap.c
Normal file
21
ocw/1/c-primer/swap.c
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright (c) 2012 MIT License by 6.172 Staff
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void swap(int i, int j) {
|
||||
int temp = i;
|
||||
i = j;
|
||||
j = temp;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int k = 1;
|
||||
int m = 2;
|
||||
swap(k, m);
|
||||
// What does this print?
|
||||
printf("k = %d, m = %d\n", k, m);
|
||||
|
||||
return 0;
|
||||
}
|
||||
111
ocw/1/c-primer/verifier.py
Normal file
111
ocw/1/c-primer/verifier.py
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
#!/usr/bin/python
|
||||
import subprocess, os, sys, re
|
||||
|
||||
def exitWithError(error):
|
||||
print error
|
||||
sys.exit(1)
|
||||
|
||||
def runAndReadOutput(args):
|
||||
if args is str:
|
||||
args = [args]
|
||||
try:
|
||||
return subprocess.check_output(args)
|
||||
except subprocess.CalledProcessError as e:
|
||||
exitWithError("ERROR: runtime error with %s" % str(args))
|
||||
|
||||
def run(path): runAndReadOutput(path)
|
||||
|
||||
def runAndCheckSizes():
|
||||
output = runAndReadOutput("./sizes")
|
||||
expected_output_format = "size of %s : %d bytes"
|
||||
|
||||
lines = set([x.replace(" ", "") for x in output.strip().lower().split('\n')])
|
||||
types = [
|
||||
( "int", 4 ),
|
||||
( "short", 2 ),
|
||||
( "long", 8 ),
|
||||
( "char", 1 ),
|
||||
( "float", 4 ),
|
||||
( "double", 8 ),
|
||||
( "unsigned int", 4 ),
|
||||
( "long long", 8 ),
|
||||
( "uint8_t", 1 ),
|
||||
( "uint16_t", 2 ),
|
||||
( "uint32_t", 4 ),
|
||||
( "uint64_t", 8 ),
|
||||
( "uint_fast8_t", 1 ),
|
||||
( "uint_fast16_t", 8 ),
|
||||
( "uintmax_t", 8 ),
|
||||
( "intmax_t", 8 ),
|
||||
( "__int128", 16 ),
|
||||
( "uint32_t", 4 ),
|
||||
( "uint64_t", 8 ),
|
||||
( "student", 8 ),
|
||||
( "x", 20),
|
||||
( "int*", 8 ),
|
||||
( "short*", 8 ),
|
||||
( "long*", 8 ),
|
||||
( "char*", 8 ),
|
||||
( "float*", 8 ),
|
||||
( "double*", 8 ),
|
||||
( "unsigned int*", 8 ),
|
||||
( "long long*", 8 ),
|
||||
( "uint8_t*", 8 ),
|
||||
( "uint16_t*", 8 ),
|
||||
( "uint32_t*", 8 ),
|
||||
( "uint64_t*", 8 ),
|
||||
( "uint_fast8_t*", 8 ),
|
||||
( "uint_fast16_t*", 8 ),
|
||||
( "uintmax_t*", 8 ),
|
||||
( "intmax_t*", 8 ),
|
||||
( "__int128*", 8 ),
|
||||
( "uint32_t*", 8 ),
|
||||
( "uint64_t*", 8 ),
|
||||
( "student*", 8 ),
|
||||
( "&x", 8)
|
||||
]
|
||||
|
||||
for typ in types:
|
||||
print (expected_output_format % typ)
|
||||
if (expected_output_format % typ).replace(" ", "") not in lines:
|
||||
exitWithError("ERROR: couldn't find type %s (or it has the incorrect value) in sizes output" % typ[0])
|
||||
|
||||
def runAndCheckSwap():
|
||||
expected_output = "k = 2, m = 1\n"
|
||||
output = runAndReadOutput("./swap")
|
||||
|
||||
if output != expected_output:
|
||||
exitWithError('ERROR: actual output: "%s", expected "%s"' % (output, expected_output))
|
||||
|
||||
def build(make_arg, filename):
|
||||
print "\nRunning make %s ... " % make_arg
|
||||
run(["make", filename])
|
||||
print "Ok!"
|
||||
|
||||
print "\nChecking that %s was built ... " % filename
|
||||
if not os.path.isfile(filename):
|
||||
exitWithError("ERROR: %s binary missing, did you rename it?" % filename)
|
||||
print "Ok!"
|
||||
|
||||
|
||||
print "Running verifying script ... "
|
||||
|
||||
print "\nChecking that the Makefile exists ... "
|
||||
if not os.path.isfile('Makefile'):
|
||||
exitWithError('ERROR: Makefile does not exist.')
|
||||
print "Good!"
|
||||
|
||||
build("sizes", "sizes")
|
||||
print "Checking output of sizes ... "
|
||||
runAndCheckSizes()
|
||||
print "Ok!"
|
||||
|
||||
build("pointer", "pointer")
|
||||
run("./pointer") # Run pointer as a sanity check, but there's no output to check
|
||||
|
||||
build("swap", "swap")
|
||||
print "Checking output of swap ... "
|
||||
runAndCheckSwap()
|
||||
print "Ok!"
|
||||
|
||||
print "LGTM"
|
||||
105
ocw/1/matrix-multiply/Makefile
Normal file
105
ocw/1/matrix-multiply/Makefile
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
# Copyright (c) 2012 MIT License by 6.172 Staff
|
||||
|
||||
# List all of your source files here (but not your headers), separated by
|
||||
# spaces. You'll have to add to this list every time you create a new
|
||||
# source file.
|
||||
SRC := testbed.c matrix_multiply.c
|
||||
|
||||
# Set the name of your binary. Change it if you like.
|
||||
PRODUCT := matrix_multiply
|
||||
|
||||
################################################################################
|
||||
# These configuration options change how your code (listed above) is compiled
|
||||
# every time you type "make". You may have to change these values to complete
|
||||
# some assignments; you should also feel free to experiment with them.
|
||||
################################################################################
|
||||
|
||||
# This option sets which compiler your code will be compiled with. Likely
|
||||
# choices are icc, icpc, gcc, g++, clang
|
||||
CC := clang
|
||||
|
||||
# These flags will be applied to your code any time it is built.
|
||||
CFLAGS := -Wall -std=c99 -D_POSIX_C_SOURCE=200809L -O3
|
||||
|
||||
# These flags are applied only if you build your code with "make DEBUG=1". -g
|
||||
# generates debugging symbols, -DDEBUG defines the preprocessor symbol "DEBUG"
|
||||
# (so that you can use "#ifdef DEBUG" in your code), and -O0 disables compiler
|
||||
# optimizations, so that the binary generated more directly corresponds to your
|
||||
# source code.
|
||||
CFLAGS_DEBUG := -g -DDEBUG -O0
|
||||
|
||||
# In the release version, we ask for many optimizations; -O3 sets the
|
||||
# optimization level to three. -DNDEBUG defines the NDEBUG macro,
|
||||
# which disables assertion checks.
|
||||
CFLAGS_RELEASE := -O1 -DNDEBUG
|
||||
|
||||
# These flags are used to invoke Clang's address sanitizer.
|
||||
CFLAGS_ASAN := -O1 -g -fsanitize=address
|
||||
|
||||
# These flags are applied when linking object files together into your binary.
|
||||
# If you need to link against libraries, add the appropriate flags here. By
|
||||
# default, your code is linked against the "rt" library with the flag -lrt;
|
||||
# this library is used by the timing code in the testbed.
|
||||
LDFLAGS := -lrt -flto -fuse-ld=gold
|
||||
|
||||
################################################################################
|
||||
# You probably won't need to change anything below this line, but if you're
|
||||
# curious about how makefiles work, or if you'd like to customize the behavior
|
||||
# of your makefile, go ahead and take a peek.
|
||||
################################################################################
|
||||
|
||||
# You shouldn't need to touch this. This keeps track of whether you are
|
||||
# building in a release or debug configuration, and sets CFLAGS appropriately.
|
||||
# (This mechanism is based on one from the original materials for 6.197 by
|
||||
# Ceryen Tan and Marek Olszewski.)
|
||||
OLDMODE=$(shell cat .buildmode 2> /dev/null)
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS := $(CFLAGS_DEBUG) $(CFLAGS)
|
||||
ifneq ($(OLDMODE),debug)
|
||||
$(shell echo debug > .buildmode)
|
||||
endif
|
||||
else ifeq ($(ASAN),1)
|
||||
CFLAGS := $(CFLAGS_ASAN) $(CFLAGS)
|
||||
LDFLAGS := $(LDFLAGS) -fsanitize=address
|
||||
ifneq ($(OLDMODE),asan)
|
||||
$(shell echo asan > .buildmode)
|
||||
endif
|
||||
else
|
||||
CFLAGS := $(CFLAGS_RELEASE) $(CFLAGS)
|
||||
ifneq ($(OLDMODE),nodebug)
|
||||
$(shell echo nodebug > .buildmode)
|
||||
endif
|
||||
endif
|
||||
|
||||
# When you invoke make without an argument, make behaves as though you had
|
||||
# typed "make all", and builds whatever you have listed here. (It knows to
|
||||
# pick "make all" because "all" is the first rule listed.)
|
||||
all: $(PRODUCT)
|
||||
|
||||
# This special "target" will remove the binary and all intermediate files.
|
||||
clean::
|
||||
rm -f $(OBJ) $(PRODUCT) .buildmode \
|
||||
$(addsuffix .gcda, $(basename $(SRC))) \
|
||||
$(addsuffix .gcno, $(basename $(SRC))) \
|
||||
$(addsuffix .gcov, $(SRC) fasttime.h)
|
||||
|
||||
# This rule generates a list of object names. Each of your source files (but
|
||||
# not your header files) produces a single object file when it's compiled. In
|
||||
# a later step, all of those object files are linked together to produce the
|
||||
# binary that you run.
|
||||
OBJ = $(addsuffix .o, $(basename $(SRC)))
|
||||
|
||||
# These rules tell make how to automatically generate rules that build the
|
||||
# appropriate object-file from each of the source files listed in SRC (above).
|
||||
%.o : %.c .buildmode
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
%.o : %.cc .buildmode
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
%.o : %.cpp .buildmode
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
# This rule tells make that it can produce your binary by linking together all
|
||||
# of the object files produced from your source files and any necessary
|
||||
# libraries.
|
||||
$(PRODUCT): $(OBJ) .buildmode
|
||||
$(CC) -o $@ $(OBJ) $(LDFLAGS)
|
||||
95
ocw/1/matrix-multiply/fasttime.h
Normal file
95
ocw/1/matrix-multiply/fasttime.h
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/**
|
||||
* Copyright (c) 2014 MIT License by 6.172 Staff
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
**/
|
||||
|
||||
#ifndef INCLUDED_FASTTIME_DOT_H
|
||||
#define INCLUDED_FASTTIME_DOT_H
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef __MACH__
|
||||
#include <mach/mach_time.h> // mach_absolute_time
|
||||
|
||||
typedef uint64_t fasttime_t;
|
||||
|
||||
|
||||
// Return the current time.
|
||||
static inline fasttime_t gettime(void) {
|
||||
return mach_absolute_time();
|
||||
}
|
||||
|
||||
// Return the time different between the start and the end, as a float
|
||||
// in units of seconds. This function does not need to be fast.
|
||||
// Implementation notes: See
|
||||
// https://developer.apple.com/library/mac/qa/qa1398/_index.html
|
||||
static inline double tdiff(fasttime_t start, fasttime_t end) {
|
||||
static mach_timebase_info_data_t timebase;
|
||||
int r = mach_timebase_info(&timebase);
|
||||
assert(r == 0);
|
||||
fasttime_t elapsed = end-start;
|
||||
double ns = (double)elapsed * timebase.numer / timebase.denom;
|
||||
return ns*1e-9;
|
||||
}
|
||||
|
||||
static inline unsigned int random_seed_from_clock(void) {
|
||||
fasttime_t now = gettime();
|
||||
return (now & 0xFFFFFFFF) + (now>>32);
|
||||
}
|
||||
|
||||
#else // LINUX
|
||||
|
||||
// We need _POSIX_C_SOURCE to pick up 'struct timespec' and clock_gettime.
|
||||
// #define _POSIX_C_SOURCE 200809L
|
||||
|
||||
#include <time.h>
|
||||
|
||||
typedef struct timespec fasttime_t;
|
||||
|
||||
// Return the current time.
|
||||
static inline fasttime_t gettime(void) {
|
||||
struct timespec s;
|
||||
#ifdef NDEBUG
|
||||
clock_gettime(CLOCK_MONOTONIC, &s);
|
||||
#else
|
||||
int r = clock_gettime(CLOCK_MONOTONIC, &s);
|
||||
assert(r == 0);
|
||||
#endif
|
||||
return s;
|
||||
}
|
||||
|
||||
// Return the time different between the start and the end, as a float
|
||||
// in units of seconds. This function does not need to be fast.
|
||||
static inline double tdiff(fasttime_t start, fasttime_t end) {
|
||||
return end.tv_sec - start.tv_sec + 1e-9*(end.tv_nsec - start.tv_nsec);
|
||||
}
|
||||
|
||||
static inline unsigned int random_seed_from_clock(void) {
|
||||
fasttime_t now = gettime();
|
||||
return now.tv_sec + now.tv_nsec;
|
||||
}
|
||||
|
||||
// Poison these symbols to help find portability problems.
|
||||
int clock_gettime(clockid_t, struct timespec *) __attribute__((deprecated));
|
||||
time_t time(time_t *) __attribute__((deprecated));
|
||||
|
||||
#endif // LINUX
|
||||
|
||||
#endif // INCLUDED_FASTTIME_DOT_H
|
||||
96
ocw/1/matrix-multiply/matrix_multiply.c
Normal file
96
ocw/1/matrix-multiply/matrix_multiply.c
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
* Copyright (c) 2012 MIT License by 6.172 Staff
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
**/
|
||||
|
||||
#include "./matrix_multiply.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
// #include "./tbassert.h"
|
||||
|
||||
// Allocates a row-by-cols matrix and returns it
|
||||
matrix* make_matrix(int rows, int cols) {
|
||||
matrix* new_matrix = malloc(sizeof(matrix));
|
||||
|
||||
// Set the number of rows and columns
|
||||
new_matrix->rows = rows;
|
||||
new_matrix->cols = cols;
|
||||
|
||||
// Allocate a buffer big enough to hold the matrix.
|
||||
new_matrix->values = (int**)malloc(sizeof(int*) * rows);
|
||||
for (int i = 0; i < rows; i++) {
|
||||
new_matrix->values[i] = (int*)malloc(sizeof(int) * cols);
|
||||
}
|
||||
|
||||
return new_matrix;
|
||||
}
|
||||
|
||||
// Frees an allocated matrix
|
||||
void free_matrix(matrix* m) {
|
||||
for (int i = 0; i < m->rows; i++) {
|
||||
free(m->values[i]);
|
||||
}
|
||||
free(m->values);
|
||||
free(m);
|
||||
}
|
||||
|
||||
// Print matrix
|
||||
void print_matrix(const matrix* m) {
|
||||
printf("------------\n");
|
||||
for (int i = 0; i < m->rows; i++) {
|
||||
for (int j = 0; j < m->cols; j++) {
|
||||
printf(" %3d ", m->values[i][j]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("------------\n");
|
||||
}
|
||||
|
||||
|
||||
// Multiply matrix A*B, store result in C.
|
||||
int matrix_multiply_run(const matrix* A, const matrix* B, matrix* C) {
|
||||
/*
|
||||
tbassert(A->cols == B->rows,
|
||||
"A->cols = %d, B->rows = %d\n", A->cols, B->rows);
|
||||
tbassert(A->rows == C->rows,
|
||||
"A->rows = %d, C->rows = %d\n", A->rows, C->rows);
|
||||
tbassert(B->cols == C->cols,
|
||||
"B->cols = %d, C->cols = %d\n", B->cols, C->cols);
|
||||
*/
|
||||
|
||||
for (int i = 0; i < A->rows; i++) {
|
||||
for (int j = 0; j < B->cols; j++) {
|
||||
for (int k = 0; k < A->cols; k++) {
|
||||
C->values[i][j] += A->values[i][k] * B->values[k][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
58
ocw/1/matrix-multiply/matrix_multiply.h
Normal file
58
ocw/1/matrix-multiply/matrix_multiply.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* Copyright (c) 2012 MIT License by 6.172 Staff
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
**/
|
||||
|
||||
|
||||
/**
|
||||
* Matrix Multiply
|
||||
*
|
||||
*
|
||||
* Declarations here are your API specification -- we expect that your
|
||||
* code defines and correctly implements these functions and does not modify
|
||||
* the way the reference implementation uses variables mentioned here,
|
||||
* so that we may call them from testbed.c and any other testing software
|
||||
* that we write!
|
||||
*
|
||||
* Deviating from this API may cause your program to fail all of our tests.
|
||||
**/
|
||||
|
||||
#ifndef MATRIX_MULTIPLY_H_INCLUDED
|
||||
|
||||
#define MATRIX_MULTIPLY_H_INCLUDED
|
||||
|
||||
typedef struct {
|
||||
int rows;
|
||||
int cols;
|
||||
int** values;
|
||||
} matrix;
|
||||
|
||||
// Multiply matrix A*B, store result in C.
|
||||
int matrix_multiply_run(const matrix* A, const matrix* B, matrix* C);
|
||||
|
||||
// Allocates a row-by-cols matrix and returns it
|
||||
matrix* make_matrix(int rows, int cols);
|
||||
|
||||
// Frees an allocated matrix
|
||||
void free_matrix(matrix* m);
|
||||
|
||||
// Print matrix
|
||||
void print_matrix(const matrix* m);
|
||||
#endif // MATRIX_MULTIPLY_H_INCLUDED
|
||||
73
ocw/1/matrix-multiply/tbassert.h
Normal file
73
ocw/1/matrix-multiply/tbassert.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
* Copyright (c) 2014 MIT License by Tao B. Schardl
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
**/
|
||||
|
||||
#ifndef _TBASSERT_H_
|
||||
#define _TBASSERT_H_ 1
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
/**************************************************************************
|
||||
* Library of debugging macros.
|
||||
*************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Print a message to STREAM when DEBUG = 1. This macro takes the
|
||||
// same arguments as FPRINTF().
|
||||
#define DEBUG_FPRINTF(STREAM, ...) \
|
||||
do { \
|
||||
fprintf(STREAM, "%s:%d (%s) ", \
|
||||
__FILE__, __LINE__, __PRETTY_FUNCTION__); \
|
||||
fprintf(STREAM, __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
// Print a message to STDERR when DEBUG = 1. This macro takes the
|
||||
// same arguments as PRINTF().
|
||||
#define DEBUG_EPRINTF(...) DEBUG_FPRINTF(stderr, __VA_ARGS__);
|
||||
|
||||
// If PREDICATE is true, do nothing. Otherwise, print an error with
|
||||
// the specified message to STDERR. This macro only operates when
|
||||
// DEBUG = 1. This macro takes a PREDICATE to evaluate followed by
|
||||
// the standard arguments to PRINTF().
|
||||
#define DEBUG_ASSERT(PREDICATE, ...) \
|
||||
do { \
|
||||
if (!(PREDICATE)) { \
|
||||
fprintf(stderr, "%s:%d (%s) Assertion " #PREDICATE " failed: ", \
|
||||
__FILE__, __LINE__, __PRETTY_FUNCTION__); \
|
||||
fprintf(stderr, __VA_ARGS__); \
|
||||
abort(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define tbassert DEBUG_ASSERT
|
||||
|
||||
#else
|
||||
|
||||
#define DEBUG_PRINTF(...) // Nothing.
|
||||
#define DEBUG_EPRINTF(...) // Nothing.
|
||||
#define DEBUG_ASSERT(...) // Nothing.
|
||||
#define tbassert(...) // Nothing.
|
||||
|
||||
#endif
|
||||
|
||||
#endif // _TBASSERT_H_
|
||||
154
ocw/1/matrix-multiply/testbed.c
Normal file
154
ocw/1/matrix-multiply/testbed.c
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
/**
|
||||
* Copyright (c) 2012 MIT License by 6.172 Staff
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
**/
|
||||
|
||||
|
||||
/**
|
||||
* testbed.c:
|
||||
*
|
||||
* This file runs your code, timing its execution and printing out the result.
|
||||
**/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "./fasttime.h"
|
||||
#include "./matrix_multiply.h"
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int optchar = 0;
|
||||
int show_usec = 0;
|
||||
int should_print = 0;
|
||||
int use_zero_matrix = 0;
|
||||
|
||||
// Always use the same seed, so that our tests are repeatable.
|
||||
unsigned int randomSeed = 1;
|
||||
|
||||
matrix* A;
|
||||
matrix* B;
|
||||
matrix* C;
|
||||
|
||||
const int kMatrixSize = 4;
|
||||
|
||||
|
||||
// Parse command line arguments
|
||||
while ((optchar = getopt(argc, argv, "upz")) != -1) {
|
||||
switch (optchar) {
|
||||
case 'u':
|
||||
show_usec = 1;
|
||||
break;
|
||||
case 'p':
|
||||
should_print = 1;
|
||||
break;
|
||||
case 'z':
|
||||
use_zero_matrix = 1;
|
||||
break;
|
||||
default:
|
||||
printf("Ignoring unrecognized option: %c\n", optchar);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// This is a trick to make the memory bug leads to a wrong output.
|
||||
int size = sizeof(int) * 4;
|
||||
int* temp[20];
|
||||
|
||||
for (int i = 0; i < 20; i++) {
|
||||
temp[i] = (int*)malloc(size);
|
||||
memset(temp[i], 1, size);
|
||||
}
|
||||
int total = 0;
|
||||
for (int i = 0; i < 20; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
total += temp[i][j];
|
||||
}
|
||||
}
|
||||
if (!total) printf("Trick to stop mallocs from being optimized out.");
|
||||
for (int i = 0; i < 20; i++) {
|
||||
free(temp[i]);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Setup\n");
|
||||
|
||||
A = make_matrix(kMatrixSize, kMatrixSize+1);
|
||||
B = make_matrix(kMatrixSize, kMatrixSize);
|
||||
C = make_matrix(kMatrixSize, kMatrixSize);
|
||||
|
||||
if (use_zero_matrix) {
|
||||
for (int i = 0; i < A->rows; i++) {
|
||||
for (int j = 0; j < A->cols; j++) {
|
||||
A->values[i][j] = 0;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < B->rows; i++) {
|
||||
for (int j = 0; j < B->cols; j++) {
|
||||
B->values[i][j] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < A->rows; i++) {
|
||||
for (int j = 0; j < A->cols; j++) {
|
||||
A->values[i][j] = rand_r(&randomSeed) % 10;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < B->rows; i++) {
|
||||
for (int j = 0; j < B->cols; j++) {
|
||||
B->values[i][j] = rand_r(&randomSeed) % 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (should_print) {
|
||||
printf("Matrix A: \n");
|
||||
print_matrix(A);
|
||||
|
||||
printf("Matrix B: \n");
|
||||
print_matrix(B);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Running matrix_multiply_run()...\n");
|
||||
|
||||
fasttime_t time1 = gettime();
|
||||
matrix_multiply_run(A, B, C);
|
||||
fasttime_t time2 = gettime();
|
||||
|
||||
if (should_print) {
|
||||
printf("---- RESULTS ----\n");
|
||||
printf("Result: \n");
|
||||
print_matrix(C);
|
||||
printf("---- END RESULTS ----\n");
|
||||
}
|
||||
|
||||
if (show_usec) {
|
||||
double elapsed = tdiff(time1, time2);
|
||||
printf("Elapsed execution time: %f usec\n",
|
||||
elapsed * (1000.0 * 1000.0));
|
||||
} else {
|
||||
double elapsed = tdiff(time1, time2);
|
||||
printf("Elapsed execution time: %f sec\n", elapsed);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
52
ocw/1/sizes.s
Normal file
52
ocw/1/sizes.s
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
.file "sizes.c"
|
||||
.text
|
||||
.globl subprocedure
|
||||
.type subprocedure, @function
|
||||
subprocedure:
|
||||
.LFB6:
|
||||
.cfi_startproc
|
||||
pushq %rbp
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_offset 6, -16
|
||||
movq %rsp, %rbp
|
||||
.cfi_def_cfa_register 6
|
||||
movl %edi, -20(%rbp)
|
||||
movl %esi, -24(%rbp)
|
||||
movl -20(%rbp), %edx
|
||||
movl -24(%rbp), %eax
|
||||
addl %edx, %eax
|
||||
movl %eax, -4(%rbp)
|
||||
nop
|
||||
popq %rbp
|
||||
.cfi_def_cfa 7, 8
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE6:
|
||||
.size subprocedure, .-subprocedure
|
||||
.globl main
|
||||
.type main, @function
|
||||
main:
|
||||
.LFB7:
|
||||
.cfi_startproc
|
||||
pushq %rbp
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_offset 6, -16
|
||||
movq %rsp, %rbp
|
||||
.cfi_def_cfa_register 6
|
||||
subq $16, %rsp
|
||||
movl $3, -8(%rbp)
|
||||
movl $5, -4(%rbp)
|
||||
movl -4(%rbp), %edx
|
||||
movl -8(%rbp), %eax
|
||||
movl %edx, %esi
|
||||
movl %eax, %edi
|
||||
call subprocedure
|
||||
movl $0, %eax
|
||||
leave
|
||||
.cfi_def_cfa 7, 8
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE7:
|
||||
.size main, .-main
|
||||
.ident "GCC: (GNU) 15.1.1 20250425"
|
||||
.section .note.GNU-stack,"",@progbits
|
||||
BIN
ocw/bit-hacks/a.out
Executable file
BIN
ocw/bit-hacks/a.out
Executable file
Binary file not shown.
2
ocw/bit-hacks/a.py
Normal file
2
ocw/bit-hacks/a.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
class S:
|
||||
def __init__(self)
|
||||
2
ocw/bit-hacks/compile_flags.txt
Normal file
2
ocw/bit-hacks/compile_flags.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
-O2
|
||||
-masm=intel
|
||||
12
ocw/bit-hacks/hacks.cc
Normal file
12
ocw/bit-hacks/hacks.cc
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
int x = 123;
|
||||
int y = 123123;
|
||||
|
||||
std::cout << x;
|
||||
std::swap(x, y);
|
||||
std::cout << y;
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
ocw/bit-hacks/structop
Executable file
BIN
ocw/bit-hacks/structop
Executable file
Binary file not shown.
15
ocw/bit-hacks/structop.cc
Normal file
15
ocw/bit-hacks/structop.cc
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#include <cstddef>
|
||||
#include <iostream>
|
||||
|
||||
struct S {
|
||||
char b;
|
||||
int i;
|
||||
};
|
||||
|
||||
int main() {
|
||||
S s;
|
||||
|
||||
std::cout << offsetof(S, i) << '\n';
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
ocw/profiling/a.out
Executable file
BIN
ocw/profiling/a.out
Executable file
Binary file not shown.
6165
ocw/profiling/cachegrind.out.1193934
Normal file
6165
ocw/profiling/cachegrind.out.1193934
Normal file
File diff suppressed because it is too large
Load diff
89225
ocw/profiling/demangled.s
Normal file
89225
ocw/profiling/demangled.s
Normal file
File diff suppressed because it is too large
Load diff
39
ocw/profiling/notes.md
Normal file
39
ocw/profiling/notes.md
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# profiling
|
||||
|
||||
## intro
|
||||
|
||||
### instrumentation: overall timing (usual idea)
|
||||
|
||||
- while timing a clock with `time_the_clock.cc`, i erroneously initialized a
|
||||
`chrono::microseconds` default. this can be seen in the STL source: the default constructor
|
||||
initializes the `Rep` (repeated value, the unit for the duration) by
|
||||
default. A `microsecond` is a long here - this became garbage.
|
||||
- NOTE: timing the clock (with 0 optimization) took ~0ns and is not of significance for my profiling. I concluded this by compiling with `-O0` and de-mangling with c++filt we can see this is the case: we can see this is the case and nothing is being optimized out:
|
||||
|
||||
```asm
|
||||
.L585:
|
||||
call std::chrono::_V2::system_clock::now()@PLT
|
||||
movq %rax, -64(%rbp)
|
||||
call std::chrono::_V2::system_clock::now()@PLT
|
||||
```
|
||||
However, I acknowledge that this code is not run one-for-one. I don't have the
|
||||
knowledge to assess caching done by the actual CPU itself, or even other side
|
||||
effects like inlining.
|
||||
|
||||
So far, though, one lesson of profiling is:
|
||||
|
||||
> Only profile the code *actually* being profiled
|
||||
|
||||
### statistical profiling
|
||||
|
||||
- more accurate by *experimental* virtue - probabilistic look
|
||||
- imagine the execution of the program as a "strip" of time
|
||||
- system-specific, but so was before
|
||||
|
||||
- statistical: stats
|
||||
- program simulation: ll
|
||||
|
||||
## exercise 1
|
||||
- use cachegrind/valgrind/asan on cf problem
|
||||
- apply bentley's rules to some code
|
||||
- begin developing a strategy for how to profile things
|
||||
26698
ocw/profiling/output.svg
Normal file
26698
ocw/profiling/output.svg
Normal file
File diff suppressed because it is too large
Load diff
|
After Width: | Height: | Size: 1.2 MiB |
BIN
ocw/profiling/perf-tester
Executable file
BIN
ocw/profiling/perf-tester
Executable file
Binary file not shown.
19
ocw/profiling/perf-tester.cc
Normal file
19
ocw/profiling/perf-tester.cc
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#include <iostream>
|
||||
|
||||
void complex_method() {
|
||||
int i = 0x12323333- 1230*123213;
|
||||
long x = -23;
|
||||
std::cout << "x: " << x << '\n';
|
||||
while (--i) {
|
||||
x ^= (x - 1);
|
||||
for (int j = 0; j < 50; ++j) {
|
||||
x = x * x * x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
complex_method();
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
ocw/profiling/perf.data
Normal file
BIN
ocw/profiling/perf.data
Normal file
Binary file not shown.
BIN
ocw/profiling/perf.data.old
Normal file
BIN
ocw/profiling/perf.data.old
Normal file
Binary file not shown.
114179
ocw/profiling/perf.script
Normal file
114179
ocw/profiling/perf.script
Normal file
File diff suppressed because it is too large
Load diff
24
ocw/profiling/time_the_clock.cc
Normal file
24
ocw/profiling/time_the_clock.cc
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <print>
|
||||
|
||||
using namespace std;
|
||||
|
||||
constexpr static size_t TRIALS = 100000;
|
||||
|
||||
|
||||
int main() {
|
||||
chrono::microseconds diffs_ms{0};
|
||||
for (size_t loop_var = 1; loop_var <= TRIALS; ++loop_var) {
|
||||
auto t1 = chrono::high_resolution_clock::now();
|
||||
auto t2 = chrono::high_resolution_clock::now();
|
||||
diffs_ms += chrono::duration_cast<chrono::microseconds>(t2 - t1);
|
||||
}
|
||||
|
||||
print("measuring the clock in c++ 23 {} trials had an average time duration "
|
||||
"of: {} microseconds, or {} milliseconds",
|
||||
TRIALS, diffs_ms / TRIALS,
|
||||
chrono::duration_cast<chrono::milliseconds>(diffs_ms / TRIALS));
|
||||
|
||||
return 0;
|
||||
}
|
||||
89225
ocw/profiling/time_the_clock.s
Normal file
89225
ocw/profiling/time_the_clock.s
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue