Created
January 19, 2022 17:34
-
-
Save mathis-m/75c9f091796b7d04321afc15071b5cd7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define _CRT_SECURE_NO_WARNINGS | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <sys/time.h> | |
#include <stdbool.h> | |
double getDifferenceTimeOfDay(struct timeval *begin, struct timeval *end) { | |
return ((end->tv_sec - begin->tv_sec) + ((end->tv_usec - begin->tv_usec)/(1000.0*1000.0))); | |
} | |
int main(int argc, char *argv[]) { | |
// get arguments passed | |
bool logToConsole = atoi(argv[1]); | |
int count = atoi(argv[2]); | |
FILE *f = NULL; | |
FILE *f2 = NULL; | |
if(logToConsole == false) { | |
// setup file headers (mode w => file wird überschrieben) | |
f = fopen("result.csv", "w"); | |
if (f == NULL) | |
{ | |
printf("Error opening file!\n"); | |
exit(1); | |
} | |
fprintf(f, "%s,%s\n", "Size", "Durchsatz"); | |
fclose(f); | |
f2 = fopen("result2.csv", "w"); | |
if (f2 == NULL) | |
{ | |
printf("Error opening file!\n"); | |
exit(1); | |
} | |
fprintf(f2, "%s,%s\n", "Size", "Time"); | |
fclose(f2); | |
} else { | |
// print table headers in console | |
printf("%s\t\t %s\t\t %s\n", "Size", "Durchsatz", "Total Time"); | |
} | |
// for 16, 64, 256, ... 16MB | |
for (unsigned long size = 16; size <= 16777216; size *= 4) { | |
int pipefd[2] = {0}; | |
int pipefdBack[2] = {0}; | |
int i, n, m; | |
char *buf; | |
char *buf2; | |
buf = malloc(size); | |
buf2 = malloc(size); | |
double mbPerS, totalTimeTaken; | |
if (buf == NULL) { | |
perror("malloc"); | |
return 1; | |
} | |
// Create Parent2Child Pipe | |
if (pipe(pipefd) == -1) { | |
perror("pipe"); | |
return 1; | |
} | |
// Create Child2Parent Pipe | |
if (pipe(pipefdBack) == -1) { | |
perror("pipe"); | |
return 1; | |
} | |
// Split process to Parent and Child Process | |
if (fork() == 0) { | |
// child Process | |
unsigned long sum = 0; | |
for (i = 0; i < count; i++) { | |
// read pipe and store bytes returned | |
n = read(pipefd[0], buf, size); | |
if (n == -1) { | |
perror("read"); | |
return 1; | |
} | |
// sum bytes to check if is equal to expected byte count | |
sum += n; | |
} | |
// check if all bytes were sent via pipe | |
if (sum != count * size) { | |
fprintf(stderr, "sum error: %ld != %ld\n", sum, count * size); | |
return 1; | |
} | |
// send back via second pipe | |
for (i = 0; i < count; i++) { | |
// write to pipe | |
size_t bytesWritten = write(pipefdBack[1], buf2, size); | |
if (bytesWritten != size) { | |
fprintf(stderr, "write size did not match: %zu bytes were written.\n", bytesWritten); | |
return 1; | |
} | |
} | |
return 0; | |
} else { | |
// parent process | |
struct timeval begin, end, totalBegin, endTotal; | |
// set begin times | |
gettimeofday(&totalBegin, NULL); | |
gettimeofday(&begin, NULL); | |
// send data to child process | |
for (i = 0; i < count; i++) { | |
// actual call to send data via pipe | |
size_t bytesWritten = write(pipefd[1], buf, size); | |
// for benchmark it makes sense to check if the size of bytes written to the pipe is the expected size | |
if (bytesWritten != size) { | |
fprintf(stderr, "write size did not match: %zu bytes were written.\n", bytesWritten); | |
return 1; | |
} | |
} | |
gettimeofday(&end, NULL); | |
// check how long it has taken to send data to child process | |
double timeTaken = getDifferenceTimeOfDay(&begin, &end); | |
// calc total bytes send per time in MiB/s | |
mbPerS = (count * size * 1.0) / (timeTaken * 1024 * 1024); | |
// read from pipe 2 | |
unsigned long sum2 = 0; | |
for (int x = 0; x < count; x++) { | |
m = read(pipefdBack[0], buf2, size); | |
if (m == -1) { | |
perror("read"); | |
return 1; | |
} | |
sum2 += m; | |
} | |
gettimeofday(&endTotal, NULL); | |
if (sum2 != count * size) { | |
fprintf(stderr, "sum2 error: %ld != %ld\n", sum2, count * size); | |
return 1; | |
} | |
// get total avg time it has taken: parent -> child -> parent | |
totalTimeTaken = getDifferenceTimeOfDay(&totalBegin, &endTotal) / count; | |
} | |
if (logToConsole == true) { | |
// log for current size, durchsatz und total time taken | |
printf("%ld byte\t\t %.0f MiB/s\t\t\t %f\n", size, mbPerS, totalTimeTaken); | |
} else { | |
// open file in append mode | |
f = fopen("result.csv", "a"); | |
if (f == NULL) | |
{ | |
printf("Error opening file!\n"); | |
exit(1); | |
} | |
// write data row for mb/s | |
fprintf(f, "%ld,%.0f\n", size, mbPerS); | |
fclose(f); | |
f2 = fopen("result2.csv", "a"); | |
if (f2 == NULL) | |
{ | |
printf("Error opening file!\n"); | |
exit(1); | |
} | |
// write data row for total time | |
fprintf(f2, "%ld,%f\n", size, totalTimeTaken); | |
fclose(f2); | |
} | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment