The University of Tokyo Written Exam 2014 Problem 4

Problem 4
The dwrite function shown below is a system call which directly writes the data in the user memory area specified by data, whose size is size bytes, to the disk.

void dwrite(void *data, int size);

The dwrite system call takes 100 μsec in addition to the disk write time. The speed of the disk write is 100 MB/sec that does not depend on the write area nor size. For example, the dwrite takes 1.1 msec for writing 100 KB data.
In this problem, 1 KB and 1 MB are defined to be 103 and 106 bytes, respectively.
Answer the following questions.
(1) Show a formula calculating the effective write performance (in MB/sec), given the write size ds bytes. Calculate the effective write performance (MB/sec) in case of writing 10 KB data to the disk by dwrite.

(2) Write a code of the following bwrite library. The bwrite library writes the write data to the buffer kept in the library. The buffer size is 100 KB. In the bwrite library, the content of the buffer is written to the disk if the data size in the buffer reaches 100KB. You must use dwrite and the following memory copy function.

void memcpy (void *dst , void *src, int byte_size);

(3) Calculate the effective write performance (MB/sec) when bwrite is called 100,000 times, each with 1-byte data. Here suppose that the memcpy function has 500 MB/sec copy performance, and that the execution time of the bwrite library solely consists of that of memcpy and the dwrite system call.

(4) Describe a method to further improve the write performance of bwrite using threads.


Here is my answer to question (1), (2), (3)
//
//  main.cpp
//  Problem4-2014
//
//  Created by Ryza 14-10-17.
//  Copyright (c) 2014年 Ryza. All rights reserved.
//

#include <iostream>

#define DWRTIE_CALLTIME 100.0f     // 100 μsec
#define BWRITE_BUF_SIZE 100*1000   // bwrite buf size 100KB

#pragma mark - (1)

static inline double dwrite_performance(unsignedlonglong);

static double dwrite_performance(unsigned long long bytes){
        // 100 MB/s -> 100 000 000 B/s -> 100 B/μsec
        //
        //         MB        /                   s
        // (bytes * 100 000) / (DWRTIE_CALLTIME + (bytes * 100 000)/100.0f)
        return bytes/(DWRTIE_CALLTIME + bytes/100.0f);
}
#pragma mark - (2)

double time_leasp = 0.0f;

int current = 0;
void * bwrite_buf;

void bwrite(void *, int);

void bwrite(void *data,int size){
        // alloc buf memory
        if (bwrite_buf == NULL) bwrite_buf = malloc(BWRITE_BUF_SIZE);
        // buffer is full, write to disk
        if (current + size >= BWRITE_BUF_SIZE)
        {
                // calculate time leasp for dwrite
                time_leasp += DWRTIE_CALLTIME + (current + size)/100.0f;
                // reset current to 0
                current = 0;
                // clear buffer
                memset(bwrite_buf, 0, BWRITE_BUF_SIZE);
        }
        // write data to buffer
        else
        {
                memcpy(bwrite_buf, &data, size);
                // calculate time leasp for memcpy
                time_leasp += size / 500.0f;
                // set current
                current += size;
        }
}

int main(int argc, const char * argv[]){
        printf("%lfMB/sn",dwrite_performance(10*1000));

#pragma mark - (3)

        for (int i = 0; i < 100000; i++) bwrite((void *)'c', 1);
        printf("%lfMB/sn",.1/(time_leasp / 1000000.0f));
        return 0;
}

Leave a Reply

Your email address will not be published. Required fields are marked *

thirteen − 8 =