This repository has been archived by the owner on Mar 23, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bench-write.omp.cpp
119 lines (111 loc) · 3.18 KB
/
bench-write.omp.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <algorithm>
#include <chrono>
#include <deque>
#include <vector>
#include <iostream>
#include <string>
#include <sys/syscall.h>
#include <unistd.h>
#include <fcntl.h>
#include "test.h"
static ::std::deque<::std::string> files;
static ::std::vector<int> fds(1, 1);
static ::std::string str = "Hello World from the GPU!\n";
static void help(int argc, char *argv[])
{
::std::cerr << "\t--out\twrite output to file\n";
::std::cerr << "\t--str\tuse given string instead of the default\n";
::std::cerr << "\t--strn\tuse given string with appended newline\n";
::std::cerr << "\t--size\tuse generated string of given size instead fo the default\n";
::std::cerr << "\t--count\twrite to n different temporary files\n";
}
static bool parse(const ::std::string &opt, const ::std::string &arg)
{
if (opt == "--out") {
::std::cerr << "writing to " << arg << " instead of stdout\n";
fds[0] = open(arg.c_str(), O_CREAT | O_WRONLY, 0666);
return true;
}
if (opt == "--str") {
::std::cerr << "Setting string to " << arg << " instead of "
<< str << "\n";
str = arg;
return true;
}
if (opt == "--strn") {
::std::cerr << "Setting string to " << arg << "(+newline) "
<< "instead of " << str << "\n";
str = arg + '\n';
return true;
}
if (opt == "--size") {
size_t size = ::std::stoi(arg);
::std::cerr << "Setting data size to " << size << " bytes.\n";
str = ::std::string(size, 'x');
return true;
}
if (opt == "--count") {
size_t count = ::std::stoi(arg);
::std::cerr << "Setting number of files to " << count << ".\n";
fds.clear();
while (count--) {
char name[] = "/tmp/gpu-sc-writeXXXXXXX";
mkstemp(name);
int fd = open(name, O_CREAT | O_WRONLY, 0666);
if (fd != -1) {
fds.push_back(fd);
files.push_back(name);
} else {
::std::cerr << "Failed to open temporary file: "
<< name << "\n";
return false;
}
}
return true;
}
return false;
}
static int run_cpu(const test_params &p, ::std::ostream &O,
int argc, char *argv[])
{
if (p.non_block) {
::std::cerr << "Non blocking syscalls on CPU are not supported\n";
return 0;
}
// HCC is very bad with globals
auto local_fds = fds;
const char * local_str_ptr = str.c_str();
uint64_t local_size = str.size();
::std::vector<int> ret(p.parallel);
auto start = ::std::chrono::high_resolution_clock::now();
#pragma omp parallel for
for (size_t i = 0; i < p.parallel; ++i)
{
int fd = local_fds[i % local_fds.size()];
for (size_t j = 0; j < p.serial; ++j) {
if (p.non_block) {
do {
ret[i] = write(fd, local_str_ptr,
local_size);
} while (ret[i] == EAGAIN);
} else {
ret[i] = write(fd, local_str_ptr, local_size);
}
}
};
auto end = ::std::chrono::high_resolution_clock::now();
auto us = ::std::chrono::duration_cast<::std::chrono::microseconds>(end - start);
O << us.count() << std::endl;
for (int fd : fds)
if (fd != 1)
close(fd);
if (::std::any_of(ret.begin(), ret.end(), [&](int ret) {
return ret != str.size(); }))
::std::cerr << "Not all return values match\n";
for (auto f : files)
remove(f.c_str());
return 0;
};
struct test test_instance = {
NULL, &run_cpu, &help, &parse, "OMP write"
};