diff --git a/Assignment_3_120040077/main.o b/Assignment_3_120040077/main.o deleted file mode 100644 index b3c85c0..0000000 Binary files a/Assignment_3_120040077/main.o and /dev/null differ diff --git a/Assignment_3_120040077/main1.cu b/Assignment_3_120040077/main1.cu new file mode 100644 index 0000000..f69df91 --- /dev/null +++ b/Assignment_3_120040077/main1.cu @@ -0,0 +1,350 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//page size is 32 bytes +#define PAGESIZE (32) +//32 KB in the shared memory +#define PHYSICAL_MEM_SIZE (32768) +//128 KB of secondary storage +#define STORAGE_SIZE (131072) +//memory segment size for each thread +#define MEMORY_SEGMENT (32768) + +//number of pages in shared memory +#define PHYSICAL_PAGE_NUM (PHYSICAL_MEM_SIZE/PAGESIZE) +//number of pages in global memory +#define STORAGE_PAGE_NUM (STORAGE_MEM_SIZE/PAGESIZE) + +#define DATAFILE "./data.bin" +#define OUTFILE "./snapshot.bin" +typedef unsigned char uchar; +typedef uint32_t u32; + +/*----------------------------------The macro below are for page table--------------------------------*/ + +#define INVALID_VALUE (0xffffffff) + +#define THREAD_PID_0 (0) +#define THREAD_PID_1 (1) +#define THREAD_PID_2 (2) +#define THREAD_PID_3 (3) + +#define PID_BIT_START (0) +#define PID_BIT_LEN (2) +#define VIRPAGE_BIT_START (PID_BIT_START+PID_BIT_LEN) +#define VIRPAGE_BIT_LEN (12) +#define COUNTER_BIT_START (VIRPAGE_BIT_START+VIRPAGE_BIT_LEN) +#define COUNTER_BIT_LEN (18) + +#define FULL_MASK (0xFFFFFFFF) +#define PID_MASK (0x3) +#define VIRPAGE_MASK (0x3FFC) +#define COUNTER_MASK (0xFFFFC000) + +#define GET_PID(x) ((x&PID_MASK)>>PID_BIT_START) +#define GET_VIRPAGE(x) ((x&VIRPAGE_MASK)>>VIRPAGE_BIT_START) +#define GET_COUNTER(x) ((x&COUNTER_MASK)>>COUNTER_BIT_START) + +#define CLEAR_PID(x) (x&(~PID_MASK)) +#define CLEAR_VIRPAGE(x) (x&(~VIRPAGE_MASK)) +#define CLEAR_COUNTER(x) (x&(~COUNTER_MASK)) + +#define SET_PID(src,value) (CLEAR_PID(src)|(value<>FIRST_PID_START) +#define GET_FIRST_VIRPAGE(x) ((x&FIRST_VIRPAGE_MASK)>>FIRST_VIRPAGE_START) +#define GET_SECOND_PID(x) ((x&SECOND_PID_MASK)>>SECOND_PID_START) +#define GET_SECOND_VIRPAGE(x) ((x&SECOND_VIRPAGE_MASK)>>SECOND_VIRPAGE_START) + +#define CLEAR_FIRST_PID(x) (x&(~FIRST_PID_MASK)) +#define CLEAR_FIRST_VIRPAGE(x) (x&(~FIRST_VIRPAGE_MASK)) +#define CLEAR_SECOND_PID(x) (x&(~SECOND_PID_MASK)) +#define CLEAR_SECOND_VIRPAGE(x) (x&(~SECOND_VIRPAGE_MASK)) + +#define SET_FIRST_PID(src,value) (CLEAR_FIRST_PID(src)|(value<0)){ + pt[i]=SET_COUNTER(pt[i],1); + valid_page_num=i; + } + else if(GET_COUNTER(pt[i])>0) + pt[i]=SET_COUNTER(pt[i],GET_COUNTER(pt[i])+1); + + //get free page + if(GET_COUNTER(pt[i])==0) + free_page_num=i; + //get LRU page + if(GET_COUNTER(pt[i])>lru_time){ + lru_time=GET_COUNTER(pt[i]); + lru_page_num=i; + } + } + if(valid_page_num!=INVALID_VALUE){ + return valid_page_num*PAGESIZE+offset; + } + else if(free_page_num!=INVALID_VALUE){ + pt[free_page_num]=SET_PID(pt[free_page_num],threadIdx.x); + pt[free_page_num]=SET_VIRPAGE(pt[free_page_num],page_num); + pt[free_page_num]=SET_COUNTER(pt[free_page_num],1); +/* for(int i=0;i0)||(i==free_page_num)) + pt[i]=SET_COUNTER(pt[i],GET_COUNTER(pt[i])+1); + }*/ + PAGEFAULT++; + return free_page_num*PAGESIZE+offset; + } + else{ + u32 swap_out_start=INVALID_VALUE; + u32 swap_in_start=INVALID_VALUE; + u32 phy_start=lru_page_num*PAGESIZE; + for(int i=0;i0)||(i==lru_page_num)) + pt[i]=SET_COUNTER(pt[i],GET_COUNTER(pt[i])+1); + }*/ + PAGEFAULT++; + return phy_start+offset; + } + +} + +__device__ uchar Gread(uchar *buffer,u32 addr) +{ + u32 page_num = addr/PAGESIZE; + u32 offset = addr%PAGESIZE; + + //addr means the addr in shared memory + addr = paging(buffer, page_num, offset); + return buffer[addr]; +} +__device__ void Gwrite(uchar *buffer, u32 addr, uchar value) +{ + u32 page_num = addr/PAGESIZE; + u32 offset = addr%PAGESIZE; + + //addr means the addr in shared memory + addr = paging(buffer, page_num, offset); + buffer[addr] = value; +} + +__device__ void snapshot(uchar *results, uchar *buffer, int offset, int input_size) +{ + for(int i=0;i=input_size-10;i--){ + __LOCK(); + int value = Gread(data,i+__GET_BASE()); + __UNLOCK(); + } + + __LOCK(); + snapshot(results+__GET_BASE(),data,__GET_BASE(),input_size); + __UNLOCK(); + //####GWrite/Gread code section end#### + printf("this thread pid = %d, total pagefault times=%u\n",threadIdx.x,PAGEFAULT); + return; +} + +int main() +{ + clock_t t; + t=clock(); + + //Load data.bin into input buffer + int input_size = load_binaryFile(DATAFILE, input, STORAGE_SIZE); + + printf("The read size is %d\n", input_size); + + //main procedure + cudaSetDevice(4); + mykernel<<<1,4,16384>>>(input_size/4); + cudaDeviceSynchronize(); + cudaDeviceReset(); + + //write binary file from results buffer + write_binaryFile(OUTFILE, results, input_size); + + t=clock()-t; + printf("total elapsed time = %f\n",((float)t)/CLOCKS_PER_SEC); + + return 0; +} \ No newline at end of file diff --git a/Assignment_3_120040077/main1.o b/Assignment_3_120040077/main1.o new file mode 100644 index 0000000..a67eb35 Binary files /dev/null and b/Assignment_3_120040077/main1.o differ diff --git a/Assignment_3_120040077/report/report.tex b/Assignment_3_120040077/report/report.tex new file mode 100644 index 0000000..81280fe --- /dev/null +++ b/Assignment_3_120040077/report/report.tex @@ -0,0 +1,18 @@ +\documentclass{article} +\usepackage[utf8]{inputenc} +\usepackage{amsmath} +\usepackage{color} +\title{CSC3150 hw5 report} +\author{Zhouliang Yu} +\date{November 2021} + +\begin{document} + +\maketitle + +\section{How to Compile} + +\section{How to Design My Program} +\subsection{} + +\end{document} diff --git a/Assignment_3_120040077/snapshot.bin b/Assignment_3_120040077/snapshot.bin index 8d757bb..ef88f4d 100644 --- a/Assignment_3_120040077/snapshot.bin +++ b/Assignment_3_120040077/snapshot.bin @@ -1358,4 +1358,4 @@ B' c;U4?5[$VaS X"3BMaU!3 X4#38Z]NNQ $/GAc[;/AONJd6'@G4OdX,5=^#4/'3N^EH/> -!E`\c/&0Z*+I.( 3 b6U]S)X)Ed.&Gb^aK<?EW.36[*>4:O#>G=E(SUO\a2$*R02)F!\O7AD-DP ;>`]I\*NM -#1<)Q[ b6KAc*-?]`bA''+bDd3V3X,[# 0Nb\)22Uac1#Z+U9*#UP&K` \RR(;OS3QT#MS$@N0 H"D,M3(VA%b0b&UUHd_1/ .7Y39X ,1)$`EZ-O 30?-a=D] \ No newline at end of file +#1<)Q[ b6KAc*-?]`bA''+bDd3V3X,[# 0Nb\)22Uac1#Z+U9*#UP&K` \RR(;OS3QT#MS$@N0 H"D,M3(VA%b0b&UUHd_1/ \ No newline at end of file diff --git a/Assignment_3_120040077/user_program.o b/Assignment_3_120040077/user_program.o deleted file mode 100644 index 399b6eb..0000000 Binary files a/Assignment_3_120040077/user_program.o and /dev/null differ diff --git a/Assignment_3_120040077/virtual_memory.cu b/Assignment_3_120040077/virtual_memory.cu index 7cf3c55..ecbfa50 100644 --- a/Assignment_3_120040077/virtual_memory.cu +++ b/Assignment_3_120040077/virtual_memory.cu @@ -42,14 +42,7 @@ __device__ bool check_page_fault(VirtualMemory *vm, u32 page_num) { return false; } -__device__ void move_to_memory(VirtualMemory *vm, u32 frame_num, u32 page_num) { - u32 original_page_num = vm->invert_page_table[frame_num]; - for (int i = 0; i < 32; i ++) { - vm->storage[original_page_num * 32 + i] = vm -> buffer[frame_num * 32 + i]; - vm->buffer[frame_num * 32 + i] = vm -> storage[page_num * 32 + i]; - } - vm -> invert_page_table[frame_num] = page_num; -} + __device__ int find_frame_number(VirtualMemory *vm, u32 page_num) { for (int i = 0; i < vm->PAGE_ENTRIES; i++) { @@ -70,13 +63,7 @@ __device__ int find_frame_num_in_frame_table(VirtualMemory *vm, u32 frame_num) return -1; } -__device__ void change_frame_table_valid_to_invalid(VirtualMemory *vm, u32 frame_num) { - int tempt = vm->invert_page_table[vm->PAGE_ENTRIES + find_frame_num_in_frame_table(vm, frame_num)]; - for (int i = find_frame_num_in_frame_table(vm, frame_num); i < vm -> PAGE_ENTRIES - 1; i ++) { - vm->invert_page_table[i + vm->PAGE_ENTRIES] = vm->invert_page_table[i + vm->PAGE_ENTRIES + 1]; - } - vm -> invert_page_table[2 * vm->PAGE_ENTRIES - 1] = tempt; -} + __device__ uchar vm_read(VirtualMemory *vm, u32 addr) { @@ -84,30 +71,55 @@ __device__ uchar vm_read(VirtualMemory *vm, u32 addr) u32 page_num = addr / 32; u32 page_offset = addr % 32; u32 frame_num; + bool isFault = false; - if (!check_page_fault(vm, page_num)) { +/** check wethere there is a fault in page table*/ + for (int i = 0; i < vm->PAGE_ENTRIES; i++) { + if (vm -> invert_page_table[i] == page_num) { + isFault = false; + }else { + isFault = true; + } + } + + + if (isFault == false) { frame_num = vm -> invert_page_table[vm->PAGE_ENTRIES]; - move_to_memory(vm, frame_num, page_num); + /** move to memory*/ + u32 original_page_num = vm->invert_page_table[frame_num]; + for (int i = 0; i < 32; i ++) { + vm->storage[original_page_num * 32 + i] = vm -> buffer[frame_num * 32 + i]; + vm->buffer[frame_num * 32 + i] = vm -> storage[page_num * 32 + i]; + } + vm -> invert_page_table[frame_num] = page_num; }else { - frame_num = find_frame_number(vm, page_num); + // frame_num = find_frame_number(vm, page_num); + /** find if there exists frame number*/ + for (int i = 0; i < vm->PAGE_ENTRIES; i++) + { + if (vm->invert_page_table[i] == page_num) + { + frame_num = i; + } + } + frame_num = -1; //out of index or not found } - change_frame_table_valid_to_invalid(vm, frame_num); -} - -__device__ void move_to_storage(VirtualMemory *vm, u32 frame_num){ - u32 page_num = vm -> invert_page_table[frame_num]; - for (int i = 0; i < 32; i ++) { - vm->storage[page_num * 32 + i] = vm->buffer[frame_num * 32 + i]; + +int tempt = vm->invert_page_table[vm->PAGE_ENTRIES + find_frame_num_in_frame_table(vm, frame_num)]; + for (int i = find_frame_num_in_frame_table(vm, frame_num); i < vm -> PAGE_ENTRIES - 1; i ++) { + vm->invert_page_table[i + vm->PAGE_ENTRIES] = vm->invert_page_table[i + vm->PAGE_ENTRIES + 1]; } + vm -> invert_page_table[2 * vm->PAGE_ENTRIES - 1] = tempt; } - -__device__ void check_frame_full(VirtualMemory *vm, u32 page_num, u32 frame_num){ - if (vm->invert_page_table[frame_num] != 0x80000000) - { - move_to_storage(vm, frame_num); - } -} +// /** swap the page from buffer to the storage*/ +// __device__ void swap(VirtualMemory *vm, u32 frame_num){ +// // u32 page_num = vm -> invert_page_table[frame_num]; +// for (int i = 0; i < 32; i ++) { +// // vm->storage[vm -> invert_page_table[frame_num] * 32 + i] = vm->buffer[frame_num * 32 + i]; +// vm->storage[(vm->invert_page_table[frame_num]) * 32 + i] = vm->buffer[frame_num * 32 + i] +// } +// } __device__ void vm_write(VirtualMemory *vm, u32 addr, uchar value) { @@ -115,23 +127,37 @@ __device__ void vm_write(VirtualMemory *vm, u32 addr, uchar value) { u32 page_num = addr / 32; u32 page_offset = addr % 32; u32 frame_num; + if(!check_page_fault(vm, page_num)) { - frame_num = vm->invert_page_table[vm->PAGE_ENTRIES]; - check_frame_full(vm,page_num,frame_num); + /** put the frame number as the top one*/ + frame_num = vm->invert_page_table[vm->PAGE_ENTRIES]; + +/** check if frame is full*/ + if (vm->invert_page_table[frame_num] != 0x80000000) + { + /** if is full move to the storage*/ + // swap(vm, frame_num); + for (int i = 0; i < 32; i++) + { + // vm->storage[vm -> invert_page_table[frame_num] * 32 + i] = vm->buffer[frame_num * 32 + i]; + vm->storage[(vm->invert_page_table[frame_num]) * 32 + i] = vm->buffer[frame_num * 32 + i] + } + } vm->invert_page_table[frame_num] = page_num; } else{ - frame_num = find_frame_number(vm, page_num); + /** LRU*/ + // frame_num = find_frame_number(vm, page_num); + } vm->buffer[frame_num * 32 + page_offset] = value; - change_frame_table_valid_to_invalid(vm, frame_num); -} -__device__ void move_to_result_buffer(VirtualMemory *vm, uchar* result, u32 page_num){ - u32 frame_num = find_frame_number(vm, page_num); - for (int i = 0; i < 32; i++){ - result[page_num * 32 + i] = vm -> buffer[frame_num * 32 + i]; // load element from vm buffer to result buffer in global memory +/** change from invalid to valid*/ + int tempt = vm->invert_page_table[vm->PAGE_ENTRIES + find_frame_num_in_frame_table(vm, frame_num)]; + for (int i = find_frame_num_in_frame_table(vm, frame_num); i < vm -> PAGE_ENTRIES - 1; i ++) { + vm->invert_page_table[i + vm->PAGE_ENTRIES] = vm->invert_page_table[i + vm->PAGE_ENTRIES + 1]; } + vm -> invert_page_table[2 * vm->PAGE_ENTRIES - 1] = tempt; } @@ -145,12 +171,36 @@ __device__ void vm_snapshot(VirtualMemory *vm, uchar *results, int offset, u32 frame_num; if (!check_page_fault(vm, page_num)) { frame_num = vm -> invert_page_table[vm -> PAGE_ENTRIES]; - move_to_memory(vm, frame_num, page_num); + u32 original_page_num = vm->invert_page_table[frame_num]; + for (int i = 0; i < 32; i ++) { + vm->storage[original_page_num * 32 + i] = vm -> buffer[frame_num * 32 + i]; + vm->buffer[frame_num * 32 + i] = vm -> storage[page_num * 32 + i]; + } + vm -> invert_page_table[frame_num] = page_num; }else{ - frame_num = find_frame_number(vm, page_num); + // frame_num = find_frame_number(vm, page_num); + /** find if there exists frame number*/ + for (int i = 0; i < vm->PAGE_ENTRIES; i++) + { + if (vm->invert_page_table[i] == page_num) + { + frame_num = i; + } + } + frame_num = -1; //out of index or not found } - move_to_result_buffer(vm, results, page_num); - change_frame_table_valid_to_invalid(vm, frame_num); + +/** move to the results buffer*/ + for (int i = 0; i < 32; i++){ + results[page_num * 32 + i] = vm -> buffer[frame_num * 32 + i]; // load element from vm buffer to result buffer in global memory + } + +/** change from invalid to valid*/ + int tempt = vm->invert_page_table[vm->PAGE_ENTRIES + find_frame_num_in_frame_table(vm, frame_num)]; + for (int i = find_frame_num_in_frame_table(vm, frame_num); i < vm -> PAGE_ENTRIES - 1; i ++) { + vm->invert_page_table[i + vm->PAGE_ENTRIES] = vm->invert_page_table[i + vm->PAGE_ENTRIES + 1]; + } + vm -> invert_page_table[2 * vm->PAGE_ENTRIES - 1] = tempt; } } diff --git a/Assignment_3_120040077/virtual_memory.o b/Assignment_3_120040077/virtual_memory.o deleted file mode 100644 index 588a1ac..0000000 Binary files a/Assignment_3_120040077/virtual_memory.o and /dev/null differ diff --git a/Assignment_3_120040077/vm b/Assignment_3_120040077/vm deleted file mode 100644 index 56551d1..0000000 Binary files a/Assignment_3_120040077/vm and /dev/null differ