├── .gitignore ├── cse-221-final-report.pdf ├── cpu_scheduling_os_services ├── Makefile ├── main.cpp ├── util.h ├── cpu.h └── cpu.cpp ├── file_system ├── file_generator.py ├── continue_read.c ├── cache_size_test.c ├── read_time_test.c ├── remote_read_test.c └── contention_read.c ├── memory ├── parser.rb ├── page_fault.c ├── ram_access_time.c └── ram_bandwidth.c ├── networking ├── setup_test.py ├── teardown_test.py ├── server.py ├── bandwidth_server.py ├── client.py └── bandwidth_client.py └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.txt 2 | *.o 3 | cpu -------------------------------------------------------------------------------- /cse-221-final-report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotcom900825/cse221/HEAD/cse-221-final-report.pdf -------------------------------------------------------------------------------- /cpu_scheduling_os_services/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | g++ main.cpp CPU.cpp -o cpu 3 | 4 | clean: 5 | rm -rf *o cpu -------------------------------------------------------------------------------- /file_system/file_generator.py: -------------------------------------------------------------------------------- 1 | # Helper function to generate random data filled test file 2 | from random import randrange 3 | import numpy 4 | 5 | array = [2, 4, 8, 16, 32, 64, 128] 6 | 7 | for x in array: 8 | 9 | fp = open("size%sk" % x, "w+") 10 | 11 | content = numpy.random.bytes(x*1024*1024) 12 | 13 | fp.write(content); 14 | fp.close() -------------------------------------------------------------------------------- /memory/parser.rb: -------------------------------------------------------------------------------- 1 | require "CSV" 2 | require "descriptive_statistics" 3 | 4 | array = Array.new(18) {|i| []} 5 | 6 | CSV.foreach("./prob_128_loop_special") do |row| 7 | row[0].split(" ").each_with_index do |cycle, i| 8 | array[i] << cycle.to_f 9 | end 10 | end 11 | 12 | array.each_with_index do |sub_array, i| 13 | puts "#{sub_array.sort[499]} #{sub_array.sort[499] * 1 / 2.6} #{sub_array.standard_deviation}" 14 | end -------------------------------------------------------------------------------- /networking/setup_test.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import time 3 | 4 | print "What's the remote host" 5 | HOST = raw_input() # The host 6 | PORT = 50007 # The same port as used by the server 7 | 8 | for i in range(0, 100): 9 | skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 10 | start = time.time() 11 | skt.connect((HOST, PORT)) 12 | end = time.time() 13 | print (end - start) * 1000 14 | skt.close() 15 | -------------------------------------------------------------------------------- /networking/teardown_test.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import time 3 | 4 | print "What's the remote host" 5 | HOST = raw_input() # The host 6 | PORT = 50007 # The same port as used by the server 7 | skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 8 | 9 | for i in range(0, 100): 10 | skt.connect((HOST, PORT)) 11 | start = time.time() 12 | skt.close() 13 | skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 14 | end = time.time() 15 | print (end - start) * 1000 16 | -------------------------------------------------------------------------------- /networking/server.py: -------------------------------------------------------------------------------- 1 | import socket 2 | 3 | HOST = '' # Symbolic name meaning the local host 4 | PORT = 50007 # Arbitrary non-privileged port 5 | skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 6 | skt.bind((HOST, PORT)) 7 | skt.listen(1) 8 | while 1: 9 | conn, addr = skt.accept() 10 | print 'Connected by', addr 11 | 12 | while 1: 13 | data = conn.recv(64) 14 | if not data: break 15 | conn.send(data) 16 | 17 | conn.close() 18 | print 'connect closed' 19 | -------------------------------------------------------------------------------- /networking/bandwidth_server.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import sys 3 | 4 | print "What's the file size" 5 | FILE_SIZE = raw_input() 6 | HOST = '' 7 | PORT = 50007 8 | skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 9 | skt.bind((HOST, PORT)) 10 | skt.listen(1) 11 | 12 | while 1: 13 | conn, addr = skt.accept() 14 | print 'Connected by', addr 15 | 16 | while 1: 17 | data = conn.recv(5) 18 | if not data: break 19 | fileData = '1' * int(FILE_SIZE) * 1024 * 1024 20 | print 'start to send %d' % sys.getsizeof(fileData) 21 | conn.send(data) 22 | conn.sendall(fileData) 23 | 24 | conn.close() 25 | print 'connect closed' -------------------------------------------------------------------------------- /networking/client.py: -------------------------------------------------------------------------------- 1 | #Benchmarking RTT 2 | 3 | import socket 4 | import time 5 | 6 | print "What's the remote host" 7 | HOST = raw_input() # The host 8 | PORT = 50007 # The same port as used by the server 9 | skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 10 | skt.connect((HOST, PORT)) 11 | 12 | fileStream = open(HOST + '.txt', 'w') 13 | for k in range(0, 100): 14 | total = 0 15 | 16 | for i in range(0, 100): 17 | start = time.time() 18 | skt.send('11111111111111111111111111111111') 19 | data = skt.recv(32) 20 | end = time.time() 21 | total += (end - start) 22 | 23 | result = (total) * 1000 / 100 24 | fileStream.write(str(result) + '\n') 25 | 26 | fileStream.close() 27 | skt.close() 28 | -------------------------------------------------------------------------------- /networking/bandwidth_client.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import time 3 | import sys 4 | 5 | print "What's the host name" 6 | HOST = raw_input() 7 | print "What's the file size" 8 | FILE_SIZE = raw_input() 9 | PORT = 50007 10 | 11 | skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 12 | skt.connect((HOST, PORT)) 13 | skt.send('start') 14 | skt.recv(5) 15 | 16 | print 'start data' 17 | total_time = 0 18 | data = '' 19 | fileSize = int(FILE_SIZE) * 1024 * 1024 20 | 21 | while (sys.getsizeof(data) < fileSize): 22 | start = time.time() 23 | data += skt.recv(fileSize) 24 | end = time.time() 25 | total_time += end - start 26 | 27 | result = total_time * 1000 28 | dataSize = sys.getsizeof(data) 29 | print dataSize 30 | average = dataSize / result #bandwidth 31 | print '%.2f %.2f' % (result, average) 32 | skt.close() 33 | -------------------------------------------------------------------------------- /cpu_scheduling_os_services/main.cpp: -------------------------------------------------------------------------------- 1 | /************************** 2 | * CSE 240 Course Project 3 | * 4 | * Xia, Yu A53041213 5 | * Xie, Chenfu A53052342 6 | * 7 | * 10 / 19 / 2014 8 | **************************/ 9 | 10 | #include "CPU.h" 11 | using namespace std; 12 | 13 | int main() { 14 | class CPU newCPU; 15 | fstream file; 16 | 17 | cout << "Start testing..." << endl; 18 | 19 | newCPU.testReadOverhead(file); 20 | 21 | newCPU.testLoopOverhead(file); 22 | 23 | newCPU.testProcedureCallOverhead(file); 24 | 25 | newCPU.testSystemCallOverhead(file); 26 | 27 | newCPU.testThreadCreationOverhead(file); 28 | 29 | newCPU.testProcessCreationOverhead(file); 30 | 31 | newCPU.testContextSwitchOverhead(file); 32 | 33 | newCPU.testThreadSwitchOverhead(file); 34 | 35 | cout << "Complete...!" << endl; 36 | return 0; 37 | } 38 | //g++ -pthread -o main main.c -lm -------------------------------------------------------------------------------- /cpu_scheduling_os_services/util.h: -------------------------------------------------------------------------------- 1 | #ifndef _UTIL_H 2 | #define _UTIL_H 3 | 4 | #define TIMES 1000000 5 | #define CREAT_TIMES 500 6 | 7 | static int fd[2]; 8 | 9 | static inline uint64_t rdtsc(void) { 10 | uint32_t lo, hi; 11 | __asm__ __volatile__("xor %%eax, %%eax;" "cpuid;" "rdtsc;": "=a" (lo), "=d" (hi)); 12 | return (((uint64_t)hi << 32) | lo); 13 | } 14 | 15 | static inline void test0(){} 16 | 17 | static inline void test1(int a1){} 18 | 19 | static inline void test2(int a1, int a2){} 20 | 21 | static inline void test3(int a1, int a2, int a3){} 22 | 23 | static inline void test4(int a1, int a2, int a3, int a4){} 24 | 25 | static inline void test5(int a1, int a2, int a3, int a4, int a5){} 26 | 27 | static inline void test6(int a1, int a2, int a3, int a4, int a5, int a6){} 28 | 29 | static inline void test7(int a1, int a2, int a3, int a4, int a5, int a6, int a7){} 30 | 31 | static inline void *foo(void *) { 32 | uint64_t t = rdtsc(); 33 | 34 | write(fd[1], (void*)&t, sizeof(uint64_t)); 35 | 36 | pthread_exit(NULL); 37 | } 38 | 39 | #endif -------------------------------------------------------------------------------- /cpu_scheduling_os_services/cpu.h: -------------------------------------------------------------------------------- 1 | #ifndef _CPU_H 2 | #define _CPU_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include #include 15 | #include #include #include #include #include #include "util.h" using namespace std; class CPU { private: double getReadOverhead(); double getLoopOverhead(); void getProcedureOverhead(vector &); double sysCallOverhead(); 16 | double threadCreationOverhead(); double processCreationOverhead(); uint64_t calculateSwitchTime(int *); double* getContextSwitchTime(); uint64_t calculateKernelSwitch(); double* getKernelSwitchOverhead(); public: void testReadOverhead(fstream &); void testLoopOverhead(fstream &); void testProcedureCallOverhead(fstream &); void testSystemCallOverhead(fstream &); void testThreadCreationOverhead(fstream &); void testProcessCreationOverhead(fstream &); void testContextSwitchOverhead(fstream &); void testThreadSwitchOverhead(fstream &); }; #endif -------------------------------------------------------------------------------- /memory/page_fault.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | static inline uint64_t rdtsc(void) { 8 | uint32_t lo, hi; 9 | __asm__ __volatile__("xor %%eax, %%eax;" "cpuid;" "rdtsc;": "=a" (lo), "=d" (hi)); 10 | return (((uint64_t)hi << 32) | lo); 11 | } 12 | 13 | int main() { 14 | int fileDes = open("random", O_RDWR); 15 | if (fileDes < 0) { 16 | printf("Open failed\n"); 17 | return -1; 18 | } 19 | unsigned int offset = 16777216; //16 MB 20 | unsigned int FILESIZE = 3435973836; //2.8 GB 21 | char* map =(char*) mmap(NULL, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fileDes, 0); 22 | 23 | char c; 24 | uint64_t start; 25 | uint64_t end; 26 | uint64_t total_time = 0; 27 | 28 | start = rdtsc(); 29 | int i; 30 | for (i = 0; i < 100; i++) 31 | { 32 | c = map[(((i+1) * offset) % (FILESIZE - 1))]; 33 | } 34 | end = rdtsc(); 35 | total_time = end - start; 36 | 37 | double averageTime = (double)(total_time - 106) / 100 - 6; 38 | printf("AvgTime: %lf\n", averageTime); 39 | munmap(map, FILESIZE); 40 | close(fileDes); 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /file_system/continue_read.c: -------------------------------------------------------------------------------- 1 | // Continuously perform read operation on designated file. To setup the 2 | // test environment for the actuall contention read program 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | const off_t BLOCKSIZE = 4*1024; 12 | const off_t FILESIZE = 64*1024*1024; 13 | 14 | 15 | void seqReadingFileProc(int fd, void* buf) 16 | { 17 | while (1) { 18 | while (read(fd, buf, BLOCKSIZE)) {} 19 | lseek(fd, 0, SEEK_SET); 20 | } 21 | } 22 | 23 | 24 | void ranReadingFileProc(int fd, void* buf) 25 | { 26 | srand((unsigned int)time(NULL)); 27 | int num = FILESIZE / BLOCKSIZE; 28 | int i; 29 | while (1) { 30 | for (i = 0; i < num; i++) { 31 | int index = rand() % num; 32 | lseek(fd, index * BLOCKSIZE, SEEK_SET); 33 | read(fd, buf, BLOCKSIZE); 34 | } 35 | } 36 | } 37 | 38 | 39 | int main(int argc, char** argv) 40 | { 41 | void *buf = malloc(BLOCKSIZE); 42 | int fd = open(argv[1], O_SYNC); 43 | if(fcntl(fd, F_NOCACHE, 1) == -1) { 44 | printf("Failed to disable cache.\n"); 45 | } 46 | uint64_t st, ed; 47 | if (argv[2][0] == '0') { 48 | seqReadingFileProc(fd, buf); 49 | } 50 | else { 51 | ranReadingFileProc(fd, buf); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /file_system/cache_size_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | const off_t BLOCKSIZE = 4*1024; 8 | 9 | static inline uint64_t rdtsc(void) { 10 | uint32_t lo, hi; 11 | __asm__ __volatile__("xor %%eax, %%eax;" "cpuid;" "rdtsc;": "=a" (lo), "=d" (hi)); 12 | return (((uint64_t)hi << 32) | lo); 13 | } 14 | 15 | int main(int argc, const char * argv[]) 16 | { 17 | void* buf = malloc(BLOCKSIZE); 18 | const off_t FILESIZE = atoll(argv[1]); 19 | int fd = open(argv[2], O_RDONLY | O_SYNC); 20 | 21 | //We first seek to the last block in the file 22 | lseek(fd, FILESIZE - 1, SEEK_SET); 23 | off_t totalBytes = 0; 24 | 25 | //Then we read the file from end to start to put the file into cache 26 | while(1){ 27 | lseek(fd, -2*BLOCKSIZE, SEEK_CUR); 28 | ssize_t bytes = read(fd, buf, BLOCKSIZE); 29 | if (bytes <= 0 || totalBytes >= FILESIZE) 30 | break; 31 | totalBytes += bytes; 32 | } 33 | 34 | close(fd); 35 | 36 | //We close the file and read it again 37 | fd = open(argv[2], O_RDONLY| O_SYNC); 38 | totalBytes = 0; 39 | 40 | //Still seek the last block in the file 41 | lseek(fd, FILESIZE - 1, SEEK_SET); 42 | 43 | uint64_t st; 44 | uint64_t ed; 45 | uint64_t total_time = 0; 46 | 47 | // Read backwards to avoid prefetching the blocks 48 | while(1){ 49 | lseek(fd, -2*BLOCKSIZE, SEEK_CUR); 50 | st = rdtsc(); 51 | ssize_t bytes = read(fd, buf, BLOCKSIZE); 52 | ed = rdtsc(); 53 | total_time += ed - st; 54 | if (bytes <= 0 || totalBytes >= FILESIZE) 55 | break; 56 | totalBytes += bytes; 57 | } 58 | 59 | close(fd); 60 | free(buf); 61 | double ans = (double)(total_time / (FILESIZE / BLOCKSIZE)) - 102; 62 | printf("%lf\n",ans); 63 | return 0; 64 | } 65 | 66 | -------------------------------------------------------------------------------- /file_system/read_time_test.c: -------------------------------------------------------------------------------- 1 | //Perform random and sequential file block read experiment 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | const off_t BLOCKSIZE = 4*1024; 11 | off_t FILESIZE; 12 | 13 | static inline uint64_t rdtsc(void) { 14 | uint32_t lo, hi; 15 | __asm__ __volatile__("xor %%eax, %%eax;" "cpuid;" "rdtsc;": "=a" (lo), "=d" (hi)); 16 | return (((uint64_t)hi << 32) | lo); 17 | } 18 | 19 | double avg_seq_time(char *file, void* buf); 20 | 21 | double avg_random_time(char *file, void* buf); 22 | 23 | int main(int argc, const char *argv[]) //input the filesize and name of file 24 | { 25 | FILESIZE = atoll(argv[1]); 26 | srand((unsigned int)time(NULL)); 27 | void *buf = malloc(BLOCKSIZE); 28 | double seq_ans = avg_seq_time(argv[2], buf); 29 | double ran_ans = avg_random_time(argv[2], buf); 30 | free(buf); 31 | printf("%.2lf %.2lf\n", seq_ans, ran_ans); // output 21 bits after point 32 | return 0; 33 | } 34 | 35 | double avg_seq_time(char *file, void* buf) 36 | { 37 | int fd = open(file, O_SYNC); 38 | if(fcntl(fd, F_NOCACHE, 1) == -1) { 39 | printf("Failed.\n"); //cannot disable cache 40 | } 41 | uint64_t st; 42 | uint64_t ed; 43 | uint64_t total_time; 44 | int count = 0; 45 | 46 | while (1) { 47 | st = rdtsc(); 48 | ssize_t bytes = read(fd, buf, BLOCKSIZE); // return #byte when read successfully 49 | if (bytes <= 0) { 50 | break; 51 | } 52 | ed = rdtsc(); 53 | total_time += ed - st; 54 | } 55 | close(fd); 56 | double num = FILESIZE / BLOCKSIZE; 57 | return total_time / num / 2.6 / 1000; 58 | } 59 | 60 | double avg_random_time(char *file, void* buf) 61 | { 62 | int i = 0; 63 | int fd = open(file, O_SYNC); //open synchronously 64 | if(fcntl(fd, F_NOCACHE, 1) == -1) //disable cache 65 | { 66 | printf("Failed.\n"); //cannot disable cache 67 | } 68 | off_t num = FILESIZE / BLOCKSIZE; 69 | 70 | uint64_t st; 71 | uint64_t ed; 72 | uint64_t total_time = 0; 73 | int count = 0; 74 | 75 | for (i = 0; i < num; i++) { 76 | off_t k = rand() % num; 77 | st = rdtsc(); 78 | lseek(fd, k * BLOCKSIZE, SEEK_SET); // offset 79 | read(fd, buf, BLOCKSIZE); 80 | ed = rdtsc(); 81 | total_time += ed - st; 82 | } 83 | close(fd); 84 | return total_time / (double)num / 2.6 / 1000; 85 | } -------------------------------------------------------------------------------- /file_system/remote_read_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | const off_t BLOCKSIZE = 4*1024; 9 | off_t FILESIZE; 10 | 11 | static inline uint64_t rdtsc(void) { 12 | uint32_t lo, hi; 13 | __asm__ __volatile__("xor %%eax, %%eax;" "cpuid;" "rdtsc;": "=a" (lo), "=d" (hi)); 14 | return (((uint64_t)hi << 32) | lo); 15 | } 16 | 17 | double avg_seq_time(char *file, void* buf); 18 | 19 | double avg_random_time(char *file, void* buf); 20 | 21 | int main(int argc, const char *argv[]) //input the filesize and name of file 22 | { 23 | FILESIZE = atoll(argv[1]); 24 | srand((unsigned int)time(NULL)); 25 | void *buf = malloc(BLOCKSIZE); 26 | int i = 0; 27 | for(i = 0; i < 10; i++){ 28 | double seq_ans = avg_random_time("/Volumes/N Nooo's Public Folder/size128", buf); 29 | printf("%.2lf\n", seq_ans); // output 21 bits after point 30 | } 31 | 32 | free(buf); 33 | return 0; 34 | } 35 | 36 | double avg_seq_time(char *file, void* buf) 37 | { 38 | int fd = open(file, O_SYNC); 39 | if(fcntl(fd, F_NOCACHE, 1) == -1) { 40 | printf("Failed.\n"); //cannot disable cache 41 | } 42 | uint64_t st; 43 | uint64_t ed; 44 | uint64_t total_time; 45 | int count = 0; 46 | 47 | while (1) { 48 | st = rdtsc(); 49 | ssize_t bytes = read(fd, buf, BLOCKSIZE); // return #byte when read successfully 50 | if (bytes <= 0) { 51 | break; 52 | } 53 | ed = rdtsc(); 54 | total_time += ed - st; 55 | } 56 | 57 | close(fd); 58 | double num = FILESIZE / BLOCKSIZE; 59 | return total_time / num / 2.6 / 1000; 60 | } 61 | 62 | double avg_random_time(char *file, void* buf) 63 | { 64 | int i = 0; 65 | int fd = open(file, O_SYNC); //open synchronously 66 | if(fcntl(fd, F_NOCACHE, 1) == -1) //disable cache 67 | { 68 | printf("Failed.\n"); //cannot disable cache 69 | } 70 | 71 | off_t num = FILESIZE / BLOCKSIZE; 72 | 73 | uint64_t st; 74 | uint64_t ed; 75 | uint64_t total_time = 0; 76 | int count = 0; 77 | 78 | 79 | for (i = 0; i < num; i++) { 80 | off_t k = rand() % num; 81 | st = rdtsc(); 82 | lseek(fd, k * BLOCKSIZE, SEEK_SET); // offset 83 | read(fd, buf, BLOCKSIZE); 84 | ed = rdtsc(); 85 | total_time += ed - st; 86 | } 87 | 88 | close(fd); 89 | return total_time / (double)num / 2.6 / 1000; 90 | } 91 | -------------------------------------------------------------------------------- /memory/ram_access_time.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define COUNT 10000 8 | #define TIMES 1000 9 | #define NANOS_PER_SECF 1000000000.0 10 | //Size of memory region that we will accessed, ranging from 4KB to 512MB 11 | int sizeList[18] = {4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288}; 12 | //The step length of KB 13 | int strideList[7] = {4, 64, 128, 1024, 1048576, 4194304, 16777216}; 14 | 15 | static mach_timebase_info_data_t info; 16 | static void __attribute__((constructor)) init_info() { 17 | mach_timebase_info(&info); 18 | } 19 | static inline uint64_t rdtsc(void) { 20 | uint32_t lo, hi; 21 | __asm__ __volatile__("xor %%eax, %%eax;" "cpuid;" "rdtsc;": "=a" (lo), "=d" (hi)); 22 | return (((uint64_t)hi << 32) | lo); 23 | } 24 | 25 | double monotonic_time(); 26 | double cacheAccessTime(int size, int strideLength); 27 | void fixedStride(int strideIndex, FILE *file, int times); 28 | 29 | int main(int argc, const char * argv[]) 30 | { 31 | FILE *file; 32 | 33 | file = fopen("prob_128_loop_special", "w"); 34 | srand((unsigned int)time(0)); 35 | fixedStride(2, file, TIMES); 36 | fclose(file); 37 | return 0; 38 | } 39 | 40 | double monotonic_time() { 41 | uint64_t time = mach_absolute_time(); 42 | double dtime = (double) time; 43 | dtime *= (double) info.numer; 44 | dtime /= (double) info.denom; 45 | return dtime / NANOS_PER_SECF; 46 | } 47 | 48 | double cacheAccessTime(int size, int strideLength) 49 | { 50 | int* A; 51 | A = (int *)malloc(size * 1024 / 4 * sizeof(int)); 52 | int num, length; 53 | length = strideLength / 4; 54 | num = size * 1024 / 4; 55 | int index; 56 | A[0] = 0; 57 | for (int i = 0; i < num; i++) { 58 | index = i + length; 59 | if (index >= num) { 60 | index %= num; 61 | } 62 | A[i] = index; 63 | } 64 | 65 | int x = 0; 66 | int64_t start; 67 | int64_t end; 68 | int64_t total_time = 0; 69 | int count = COUNT; 70 | 71 | start = rdtsc(); 72 | for (int i = 0; i < count; i++) { 73 | x = A[x]; 74 | } 75 | end = rdtsc(); 76 | total_time = end - start; 77 | double ans = (total_time - 106) / count - 6; 78 | free(A); 79 | return ans; 80 | } 81 | 82 | void fixedStride(int strideIndex, FILE *file, int ts) 83 | { 84 | for (int i = 0; i < ts; i++) { 85 | for (int j = 0; j < 18; i++) { 86 | double averageTime = cacheAccessTime(sizeList[j], strideList[strideIndex]); 87 | fprintf(file, "%lf ", averageTime); 88 | } 89 | fprintf(file, "\n"); 90 | } 91 | return ; 92 | } -------------------------------------------------------------------------------- /memory/ram_bandwidth.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define Offset 3*pow(2,10) 9 | #define loops 10000 10 | #define counts 1000 11 | #define Memory 26 12 | #define NANOS_PER_SECF 1000000000.0 13 | 14 | static inline uint64_t rdtsc(void) { 15 | uint32_t lo, hi; 16 | __asm__ __volatile__("xor %%eax, %%eax;" "cpuid;" "rdtsc;": "=a" (lo), "=d" (hi)); 17 | return (((uint64_t)hi << 32) | lo); 18 | } 19 | 20 | static mach_timebase_info_data_t info; 21 | 22 | static void __attribute__((constructor)) init_info() { 23 | mach_timebase_info(&info); 24 | } 25 | 26 | double monotonic_time(); 27 | double wirteTime(int *A, int counter); 28 | double readTime(int *A, int counter); 29 | 30 | int main(int argc, char const *argv[]) 31 | { 32 | int power = Memory; 33 | int counter = 1; 34 | for(int k = 0; k < power; k++) { 35 | counter = counter * 2; 36 | } 37 | int *A = (int *)malloc(counter * sizeof(int)); 38 | for (int j = 0; j < counter; ++j) 39 | { 40 | A[j] = 0; 41 | } 42 | 43 | double wtTime; 44 | double rdTime; 45 | int rwTimes = counts; 46 | 47 | FILE *file1, *file2; 48 | file1 = fopen("RAM_wr_bandwidth","w+"); 49 | file2 = fopen("RAM_rd_bandwidth","w+"); 50 | for (int i = 0; i < rwTimes; ++i){ 51 | wtTime = wirteTime(A, counter); 52 | rdTime = readTime(A, counter); 53 | fprintf(file1, "%f\n", wtTime); 54 | fprintf(file2, "%f\n", rdTime); 55 | } 56 | 57 | fclose(file1); 58 | fclose(file2); 59 | return 0; 60 | } 61 | 62 | double monotonic_time() { 63 | uint64_t time = mach_absolute_time(); 64 | double dtime = (double) time; 65 | dtime *= (double) info.numer; 66 | dtime /= (double) info.denom; 67 | return dtime / NANOS_PER_SECF; 68 | } 69 | 70 | double wirteTime(int* A, int counter) { 71 | double start = 0; 72 | double end = 0; 73 | int i = 0; 74 | int j = 0; 75 | int ofset = Offset; 76 | 77 | double total_time = 0; 78 | start = monotonic_time(); 79 | while(j < loops) 80 | { 81 | j++; 82 | for (int k = 0; k < counter; k++){ 83 | A[k] = 0; 84 | } 85 | 86 | } 87 | end = monotonic_time(); 88 | total_time = end - start; 89 | 90 | double cost = 4 * counter * loops; 91 | return (cost / total_time); 92 | } 93 | 94 | double readTime(int *A, int counter) { 95 | uint64_t start = 0; 96 | uint64_t end = 0; 97 | int a = 0; 98 | int i = 0, j = 0; 99 | int ofset = Offset; 100 | 101 | int total_time = 0; 102 | while (j < loops) 103 | { 104 | start = rdtsc(); 105 | j++; 106 | i = i + ofset; 107 | i = i % counter; 108 | for (int k = 0; k < 1000; k++) { 109 | a = A[i+k]; 110 | } 111 | end = rdtsc(); 112 | total_time += end - start; 113 | } 114 | double timecost = total_time - (j+1)*29; 115 | double cost = 4 * 1000 * (j+1) / pow(2, 20); 116 | return (cost / (timecost * 0.56 * pow(10,-9))); 117 | } -------------------------------------------------------------------------------- /file_system/contention_read.c: -------------------------------------------------------------------------------- 1 | // This code snippet is implemented, tested on the local environment 2 | // but the result is not too promising, so we shift to the approach 3 | // described in the report, but we still leave the code snippet here. 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | off_t FILESIZE; 13 | 14 | static inline uint64_t rdtsc(void) { 15 | uint32_t lo, hi; 16 | __asm__ __volatile__("xor %%eax, %%eax;" "cpuid;" "rdtsc;": "=a" (lo), "=d" (hi)); 17 | return (((uint64_t)hi << 32) | lo); 18 | } 19 | 20 | void readFile(char *file, int seq){ 21 | void *buf = malloc(4096); 22 | 23 | char *files[] = {"size64k_0", "size64k_1", "size64k_2", "size64k_3", "size64k_4", "size64k_5", "size64k_6", "size64k_7", "size64k_8", "size64k_9"}; 24 | 25 | int fd = open(files[seq], O_RDONLY); 26 | 27 | if(fcntl(fd, F_NOCACHE, 1) == -1) { 28 | printf("Failed.\n"); //cannot disable cache 29 | } 30 | 31 | uint64_t st; 32 | uint64_t ed; 33 | uint64_t total_time; 34 | while(1){ 35 | st = rdtsc(); 36 | ssize_t bytes = read(fd, buf, 4096); 37 | if(bytes <= 0){ 38 | break; 39 | } 40 | ed = rdtsc(); 41 | total_time += ed - st; 42 | } 43 | close(fd); 44 | double num = FILESIZE / 4096; 45 | printf("%.2lf\n", total_time / num / 2.6 / 1000); // output 21 bits after point 46 | 47 | } 48 | 49 | void readFileRandomly(char *file, int seq){ 50 | void *buf = malloc(4096); 51 | char *files[] = {"size64k_0", "size64k_1", "size64k_2", "size64k_3", "size64k_4", "size64k_5", "size64k_6", "size64k_7", "size64k_8", "size64k_9"}; 52 | int fd = open(files[seq], O_RDONLY); 53 | 54 | if(fcntl(fd, F_NOCACHE, 1) == -1) { 55 | printf("Failed.\n"); //cannot disable cache 56 | } 57 | 58 | off_t num = FILESIZE / 4096; 59 | off_t *access_list = (off_t*)malloc(num * sizeof(off_t)); 60 | int i; 61 | for (i = 0; i < num; i++) 62 | { 63 | access_list[i] = rand() % num; 64 | } 65 | 66 | double st; 67 | double ed; 68 | double total_time; 69 | 70 | for (i = 0; i < num; i++) { 71 | st = rdtsc(); 72 | lseek(fd, access_list[i] * 4096, SEEK_SET); // offset 73 | read(fd, buf, 4096); 74 | ed = rdtsc(); 75 | total_time += ed - st; 76 | } 77 | 78 | close(fd); 79 | printf("%.2lf\n", total_time / (double)num / 2.6 / 1000); // output 21 bits after point 80 | 81 | } 82 | 83 | int main(int argc, char const *argv[]) 84 | { 85 | /* code */ 86 | FILESIZE = atoll(argv[1]); 87 | srand((unsigned int)time(NULL)); 88 | 89 | pid_t pids[10]; 90 | int i; 91 | int n = atoll(argv[3]); 92 | printf("\n"); 93 | /* Start children. */ 94 | for (i = 0; i < n; ++i) { 95 | if ((pids[i] = fork()) < 0) { 96 | perror("fork"); 97 | abort(); 98 | } else if (pids[i] == 0) { 99 | readFileRandomly(argv[2], i); 100 | exit(0); 101 | }else{ 102 | //readFile(argv[2]); 103 | } 104 | } 105 | 106 | return 0; 107 | } 108 | 109 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## CSE221 project source code [Github Link](https://github.com/dotcom900825/cse221) 2 | ### CPU, Scheduling, and OS Services 3 | To run the CPU, Scheduling, OS Services test, there will be no any specific input parameter. All the test functions will run automatically and outputs in the corresponding txt files. If you want to run a specific test, you can do so by commenting out other tests in the main function. 4 | 5 | We provide the makefile along the way, you can complie the source code by running 6 | ```sh 7 | $ make 8 | ``` 9 | **Output file description** 10 | * **Read_Overhead.txt**: contains the average measured CPU cycle counts for reading from RTDSC call related registers. 11 | 12 | * **Procedure_Call_Overhead.txt**: contains the average measured CPU cycle counts of calling functions with different arguments from 0 ~ 7. 13 | 14 | * **System_Call_Overhead.txt**: contains the average measured CPU cycles overhead of making system call. 15 | 16 | * **Thread_Creation_Overhead.txt**: contains the average measured CPU cycle overhead used to create a kernel thread. 17 | 18 | * **Process_Creation_Overhead.txt**: contains the overhead used to create a process. 19 | 20 | * **Context_Switch_Overhead.txt** contains the context switch time between different processes. 21 | 22 | * **Kernel_Switch_Overhead.txt**: contains the overhead to do the kernel thread switch. 23 | 24 | ###Memory 25 | * **RAM access time**: For the RAM access time, we can use ram_access_time.c to conduct the experiment. To run the test, we need to specify the output test data file and the stride size. Then we can just run the test command by the following command. The out file will contain the CPU cycle count for individual integer accesses for different size of memory regions. 26 | ```sh 27 | $ ./ram_access_time 28 | ``` 29 | 30 | * **RAM bandwidth**: For the ram bandwidth measurement, we can use the ram_bandwidth.c, it will generate two output files, RAM_wr_bandwidth and RAM_rd_bandwidth 31 | 32 | * **Page fault service time**: For the page fault service time experiment, we can use the page_fault.c. Before we conduct the experiment, we need to first generate a big testing file filled with random data. We can create one by running the following command 33 | ```sh 34 | $ dd if=/dev/urandom of=random bs=1048576 count=3072 35 | ``` 36 | Then we can run the page_fault command which will generate 37 | 38 | ###Network 39 | * **Round Trip Time**: For the RTT measurement, we use the client.py and server.py to conduct this experiment. First on the remote server, you can run the server.py as following: 40 | ```sh 41 | $ python server.py 42 | ``` 43 | Then on the client side, you can run the client.py as following: 44 | ```sh 45 | $ python client.py 46 | ``` 47 | Then type in the remote server ip address, or if you want to perform local round trip time measurement then you can run server.py and client.py on the same machine and put 127.0.0.1 for the ip address. The results will get output to the txt file named by the remote ip address you used. 48 | 49 | * **Peak bandwidth**: For the peak bandwidth measurement, we can run the bandwidth_server.py on the remote side and bandwidth_client.py on the local environment to test remote bandwidth. Then we can run both client and server in the local environment to test the local bandwidth. We can specify the test file size and host info when we start the client and server program. 50 | On the server side: 51 | ```sh 52 | $ python bandwidthServer.py 53 | What's the file size 54 | 32 55 | ``` 56 | On the client side: 57 | ```sh 58 | $ python bandwidthClient.py 59 | What's the host name 60 | 127.0.0.1 61 | What's the file size 62 | 32 63 | ``` 64 | 65 | * **Connection overhead**: For the connection overhead experiment, we need to fire up server program on the remote machine by just running server.py, and on the local environment we run the setup_test.py and teardown_test.py to measure connection setup overhead and connection teardown overhead respectively. 66 | 67 | ### File System 68 | Before you start running the test, you might need to prepare some randomly filled test file in different size. We provide a util python script for that purpose: file_generator.py. By modifying the bytes parameters, you can generate different test file size on demand. 69 | 70 | * To measure the **system file cache size**, we can use cache_size_test.c, after compile it, you can run the command as following, let's say you want to test reading 4GB size data from a 5G test file called 5gb_file. 71 | ```sh 72 | $ ./cache_size_test 5368709120 5gb_file 73 | ``` 74 | 75 | * To measure the **File read time**, we can use read_time_test.c, after compile it, you can run the command in the following way. You can generate a series of test files in different size by using GenerateFile.py. The command will out put two columns of data every time, first column is sequential access time in us, the second column is random access time in us. 76 | ```sh 77 | $ ./read_time_test 2097152 2mb_file 78 | ``` 79 | 80 | * To measure the **remote file read time**, we need to setup the testing environment first. In our setup, one Macbook serves as NFS and enable file sharing for all the testing files. The other Macbook serves as client and mout the NFS's folder onto its file system. Then we use the remote_read_time.c to experiment sequential and random read time. Unfortunately, before you start the test, you need to modify the file path within the source code. 81 | ```sh 82 | $ ./remote_read_test 16777216 83 | ``` 84 | 85 | * To measure the **Contention**:, we need to first run a number of processes performing random or sequential read continueslly. We do that by running the read_time_contention.c as following. The second parameter control whether it keep reading sequentially or randomely, 1 for random read and 0 for sequential read. 86 | * 87 | ```sh 88 | $ ./read_time_contention testFile 1 89 | ``` 90 | Then we can fire up another process, that run the previous used read_time_test.c on a different file. This can guarantee that there are a number of processes reading different files and another one performing measurement. 91 | 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /cpu_scheduling_os_services/cpu.cpp: -------------------------------------------------------------------------------- 1 | #include "CPU.h" 2 | #include "util.h" 3 | 4 | void* runThread(void *) { 5 | pthread_exit(NULL); 6 | } 7 | 8 | //Measure read overhead 9 | double CPU::getReadOverhead() { 10 | double sum = 0; 11 | uint64_t start, end; 12 | rdtsc(); 13 | for (int i = 0; i < TIMES; i++) { 14 | start = rdtsc(); 15 | end = rdtsc(); 16 | sum = sum + (end - start); 17 | } 18 | 19 | return ((double)sum) / ((double)(TIMES)); 20 | } 21 | 22 | // Measure loop overhead 23 | double CPU::getLoopOverhead() { 24 | uint64_t start; 25 | uint64_t end; 26 | 27 | rdtsc(); 28 | uint64_t total_time = 0; 29 | start = rdtsc(); 30 | for (int i = 0; i < TIMES; i++) { 31 | } 32 | end = rdtsc(); 33 | total_time += end - start; 34 | 35 | return (double)total_time / TIMES; 36 | } 37 | 38 | // Measure procedure call overhead with different size of arrays 39 | void CPU::getProcedureOverhead(vector &ans) { 40 | uint64_t start; 41 | uint64_t end; 42 | uint64_t s = 0; 43 | uint64_t total_time = 0; 44 | rdtsc(); 45 | 46 | for (int i = 0; i < TIMES; i++) { 47 | start = rdtsc(); 48 | test0(); 49 | end = rdtsc(); 50 | 51 | total_time += (end - start); 52 | } 53 | ans[0] = (double)total_time / (double)TIMES; 54 | 55 | rdtsc(); 56 | total_time = 0; 57 | for (int i = 0; i < TIMES; i++) { 58 | start = rdtsc(); 59 | test1(1); 60 | end = rdtsc(); 61 | 62 | total_time += end - start; 63 | } 64 | ans[1] = (double)total_time / (double)TIMES; 65 | 66 | rdtsc(); 67 | total_time = 0; 68 | for (int i = 0; i < TIMES; i++) { 69 | start = rdtsc(); 70 | test2(1, 2); 71 | end = rdtsc(); 72 | 73 | total_time += end - start; 74 | } 75 | ans[2] = (double)total_time / (double)TIMES; 76 | 77 | rdtsc(); 78 | total_time = 0; 79 | for (int i = 0; i < TIMES; i++) { 80 | start = rdtsc(); 81 | test3(1, 2, 3); 82 | end = rdtsc(); 83 | 84 | total_time += end - start; 85 | } 86 | ans[3] = (double)total_time / (double)TIMES; 87 | 88 | rdtsc(); 89 | total_time = 0; 90 | for (int i = 0; i < TIMES; i++) { 91 | start = rdtsc(); 92 | test4(1, 2, 3, 4); 93 | end = rdtsc(); 94 | 95 | total_time += end - start; 96 | } 97 | ans[4] = (double)total_time / (double)TIMES; 98 | 99 | rdtsc(); 100 | total_time = 0; 101 | for (int i = 0; i < TIMES; i++) { 102 | start = rdtsc(); 103 | test5(1, 2, 3, 4, 5); 104 | end = rdtsc(); 105 | 106 | total_time += end - start; 107 | } 108 | ans[5] = (double)total_time / (double)TIMES; 109 | 110 | rdtsc(); 111 | total_time = 0; 112 | for (int i = 0; i < TIMES; i++) { 113 | start = rdtsc(); 114 | test6(1, 2, 3, 4, 5, 6); 115 | end = rdtsc(); 116 | 117 | total_time += end - start; 118 | } 119 | ans[6] = total_time / (double)TIMES; 120 | 121 | rdtsc(); 122 | total_time = 0; 123 | for (int i = 0; i < TIMES; i++) { 124 | start = rdtsc(); 125 | test7(1, 2, 3, 4, 5, 6, 7); 126 | end = rdtsc(); 127 | 128 | total_time += end - start; 129 | } 130 | ans[7] = (double)total_time / (double)TIMES; 131 | 132 | return; 133 | } 134 | 135 | // Measure system call overhead 136 | double CPU::sysCallOverhead() { 137 | uint64_t start; 138 | uint64_t end; 139 | uint64_t total_time = 0; 140 | 141 | for (int i = 0; i < TIMES; i++) { 142 | rdtsc(); 143 | start = rdtsc(); 144 | getppid(); 145 | end = rdtsc(); 146 | 147 | total_time += end - start; 148 | } 149 | 150 | return (double)total_time / (double)TIMES; 151 | } 152 | 153 | // Measure thread create overhead by using posix thread library 154 | double CPU::threadCreationOverhead() { 155 | pthread_t td; 156 | uint64_t start, end, total_time; 157 | total_time = 0; 158 | 159 | for (int i = 0; i < CREAT_TIMES; i++) { 160 | rdtsc(); 161 | start = rdtsc(); 162 | 163 | pthread_create(&td, NULL, runThread, NULL); 164 | pthread_join(td, NULL); 165 | 166 | end = rdtsc(); 167 | total_time += end - start; 168 | } 169 | 170 | return (double)total_time / (double)CREAT_TIMES; 171 | } 172 | 173 | // Measure process creation overhead 174 | double CPU::processCreationOverhead() { 175 | uint64_t start; 176 | uint64_t end; 177 | uint64_t total_time = 0; 178 | pid_t pid; 179 | 180 | for (int i = 0; i < CREAT_TIMES; i++) { 181 | rdtsc(); 182 | start = rdtsc(); 183 | pid = fork(); 184 | 185 | if (pid == 0) { 186 | exit(1); 187 | } 188 | else { 189 | wait(NULL); 190 | end = rdtsc(); 191 | total_time = total_time + end - start; 192 | } 193 | } 194 | 195 | return (double)total_time / (double)CREAT_TIMES; 196 | 197 | } 198 | 199 | // Measure process context switch overhead 200 | uint64_t CPU::calculateSwitchTime(int *fd) { 201 | uint64_t start; 202 | uint64_t end; 203 | pid_t cpid; 204 | uint64_t result = 0; 205 | 206 | if ((cpid = fork()) != 0) { 207 | rdtsc(); 208 | start = rdtsc(); 209 | 210 | wait(NULL); 211 | read(fd[0], (void*)&end, sizeof(uint64_t)); 212 | } 213 | else { 214 | end = rdtsc(); 215 | 216 | write(fd[1], (void*)&end, sizeof(uint64_t)); 217 | exit(1); 218 | } 219 | if(end > start){ 220 | result = end - start; 221 | } 222 | return (result); 223 | } 224 | 225 | // Helper funtion to calculate average process context switch time 226 | double* CPU::getContextSwitchTime() { 227 | int fd[2]; 228 | pipe(fd); 229 | uint64_t s[CREAT_TIMES]; 230 | double sum = 0; 231 | int i = 0; 232 | 233 | while(i < CREAT_TIMES) { 234 | uint64_t res = calculateSwitchTime(fd); 235 | if (res > 0) { 236 | s[i] = res; 237 | sum += s[i]; 238 | ++i; 239 | } 240 | } 241 | 242 | static double res; 243 | res = (double)sum / (double)CREAT_TIMES; 244 | 245 | return res; 246 | } 247 | 248 | //Calculate thread context switch time 249 | uint64_t CPU::calculateKernelSwitch() { 250 | uint64_t threadSt; 251 | uint64_t threadEd; 252 | 253 | pthread_t thread; 254 | pipe(fd); 255 | pthread_create(&thread, NULL, foo, NULL); 256 | 257 | rdtsc(); 258 | 259 | threadSt = rdtsc(); 260 | pthread_join(thread, NULL); 261 | read(fd[0], (void*)&threadEd, sizeof(uint64_t)); 262 | 263 | return threadEd - threadSt; 264 | } 265 | 266 | // Helper funtion to calculate average thread context switch time 267 | double* CPU::getKernelSwitchOverhead() { 268 | uint64_t s[CREAT_TIMES]; 269 | double sum = 0.0; 270 | double tmp = 0.0; 271 | 272 | int i = 0; 273 | while (i < CREAT_TIMES) { 274 | uint64_t res = calculateKernelSwitch(); 275 | 276 | if (res > 0) { 277 | s[i] = res; 278 | sum += s[i]; 279 | i++; 280 | } 281 | } 282 | 283 | static double res[2]; 284 | res[0] = sum / (double)CREAT_TIMES; 285 | 286 | for(i = 0; i < CREAT_TIMES; ++i) { 287 | tmp += (double)(s[i] - res[0]) * (double)(s[i] - res[0]); 288 | } 289 | 290 | res[1] = sqrt(tmp / (double)(CREAT_TIMES - 1)); 291 | return res; 292 | } 293 | 294 | // From here are all the util function to wrap around previous actuall test functions 295 | void CPU::testReadOverhead(fstream &file) { 296 | cout << "Getting Read Overhead..." << endl; 297 | 298 | file.open("Read_Overhead.txt", ios::out); 299 | if (file == NULL) { 300 | cout << "File open failed!" << endl; 301 | return; 302 | } 303 | for (int i = 0; i < 10; i++) { 304 | file << setiosflags(ios::fixed) << getReadOverhead() << "\n"; 305 | } 306 | file.close(); 307 | } 308 | 309 | void CPU::testLoopOverhead(fstream &file) { 310 | cout << "Getting Loop Overhead..." << endl; 311 | 312 | file.open("Loop_Overhead.txt", ios::out); 313 | if (file == NULL) { 314 | cout << "File open failed!" << endl; 315 | return; 316 | } 317 | for (int i = 0; i < 10; i++) { 318 | file << setiosflags(ios::fixed) << getLoopOverhead() << "\n"; 319 | } 320 | file.close(); 321 | } 322 | 323 | void CPU::testProcedureCallOverhead(fstream &file) { 324 | cout << "Getting Procedure Call Overhead..." << endl; 325 | file.open("Procedure_Call_Overhead.txt", ios::out); 326 | if (file == NULL) { 327 | cout << "File open failed!" << endl; 328 | return; 329 | } 330 | for (int i = 0; i < 10; i++) { 331 | vector result(8, 0.0); 332 | getProcedureOverhead(result); 333 | 334 | file << setiosflags(ios::fixed) 335 | << result[0] << " " 336 | << result[1] << " " 337 | << result[2] << " " 338 | << result[3] << " " 339 | << result[4] << " " 340 | << result[5] << " " 341 | << result[6] << " " 342 | << result[7] << "\n"; 343 | double increment = (result[7] + result[6] + result[5] + result[4] - result[3] - result[2] - result[1] - result[0]) / 16; 344 | file << setiosflags(ios::fixed) << increment << "\n"; 345 | } 346 | file.close(); 347 | } 348 | 349 | void CPU::testSystemCallOverhead(fstream &file) { 350 | cout << "Getting System Call Overhead..." << endl; 351 | file.open("System_Call_Overhead.txt", ios::out); 352 | if (file == NULL) { 353 | cout << "File open failed!" << endl; 354 | return; 355 | } 356 | for (int i = 0; i < 10; i++) { 357 | file << setiosflags(ios::fixed) << sysCallOverhead() << "\n"; 358 | } 359 | file.close(); 360 | } 361 | 362 | void CPU::testThreadCreationOverhead(fstream &file) { 363 | cout << "Getting Thread Creation Overhead..." << endl; 364 | file.open("Thread_Creation_Overhead.txt", ios::out); 365 | if (file == NULL) { 366 | cout << "File open failed!" << endl; 367 | return; 368 | } 369 | for (int i = 0; i < 10; i++) { 370 | file << setiosflags(ios::fixed) << threadCreationOverhead() << "\n"; 371 | } 372 | file.close(); 373 | } 374 | 375 | void CPU::testProcessCreationOverhead(fstream &file) { 376 | cout << "Getting Process Creation Overhead..." << endl; 377 | file.open("Process_Creation_Overhead.txt", ios::out); 378 | if (file == NULL) { 379 | cout << "File open failed!" << endl; 380 | return; 381 | } 382 | for (int i = 0; i < 10; i++) { 383 | file << setiosflags(ios::fixed) << processCreationOverhead() << "\n"; 384 | } 385 | file.close(); 386 | } 387 | 388 | void CPU::testContextSwitchOverhead(fstream &file) { 389 | cout << "Getting Context Switch Overhead..." << endl; 390 | file.open("Context_Switch_Overhead.txt", ios::out); 391 | if (file == NULL) { 392 | cout << "File open failed!" << endl; 393 | return; 394 | } 395 | for (int i = 0; i < 10; i++) { 396 | double contextSwitchAvg = getContextSwitchTime(); 397 | 398 | file << setiosflags(ios::fixed) 399 | << contextSwitchAvg[0] << "\n"; 400 | } 401 | file.close(); 402 | } 403 | 404 | void CPU::testThreadSwitchOverhead(fstream &file) { 405 | cout << "Getting Thread Switch Overhead..." << endl; 406 | file.open("Kernel_Switch_Overhead.txt", ios::out); 407 | if (file == NULL) { 408 | cout << "File open failed!" << endl; 409 | return; 410 | } 411 | for (int i = 0; i < 10; i++) { 412 | double* kernelSwitchAvg = getKernelSwitchOverhead(); 413 | 414 | file << setiosflags(ios::fixed) 415 | << kernelSwitchAvg[0] << " " 416 | << kernelSwitchAvg[1] << "\n"; 417 | } 418 | file.close(); 419 | } --------------------------------------------------------------------------------