Skip to content

Instantly share code, notes, and snippets.

@zarzen
Created April 1, 2020 20:43
Show Gist options
  • Save zarzen/a063c14f18fc37cf7b6f89990fac49bc to your computer and use it in GitHub Desktop.
Save zarzen/a063c14f18fc37cf7b6f89990fac49bc to your computer and use it in GitHub Desktop.
multi-thread-memcpy
#include <iostream>
#include <chrono>
#include <sys/mman.h>
#include <cstring>
#include <thread>
#include <vector>
static const char integ_alphabet[] =
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
static const int integ_alphabet_length =
(sizeof(integ_alphabet) / sizeof(*integ_alphabet)) - 1;
void ft_fill_buf(void *buf, int size) {
char *msg_buf;
int msg_index;
static unsigned int iter = 0;
int i;
msg_index = ((iter++) * 7) % integ_alphabet_length;
msg_buf = (char *)buf;
for (i = 0; i < size; i++) {
msg_buf[i] = integ_alphabet[msg_index++];
if (msg_index >= integ_alphabet_length)
msg_index = 0;
}
};
double time_now() {
auto t = std::chrono::high_resolution_clock::now();
return t.time_since_epoch().count() / 1e9; // convert to seconds
};
bool verify_value(char* b1, char* b2, size_t len) {
bool ret = true;
for (int i = 0; i < len; i ++) {
if (*(b1 + i) != *(b2 + i))
ret = false;
}
return ret;
}
void mthd_memcpy(char* dst, char* src, size_t len, int n_worker) {
std::vector<std::thread> thds;
if (n_worker < 1)
std::cerr << "at least 1 worker for memcpy\n";
size_t trunk_size = len / n_worker;
size_t handled_size = 0;
for (int i = 0; i < n_worker - 1; i ++ ) {
char* _s = src + i * trunk_size;
char* _d = dst + i * trunk_size;
thds.push_back(std::thread(memcpy, _d, _s, trunk_size));
handled_size += trunk_size;
}
size_t remaining = len - handled_size;
char* _s = src + handled_size;
char* _d = dst + handled_size;
thds.push_back(std::thread(memcpy, _d, _s, remaining));
for (int i = 0; i < n_worker; i ++) {
thds[i].join();
}
}
int main() {
size_t buf_size = 300 * 1024 * 1024;
char* src_buf = new char[buf_size];
char* dst_buf = new char[buf_size];
mlock(src_buf, buf_size);
mlock(dst_buf, buf_size);
// fill buf
ft_fill_buf(src_buf, buf_size);
std::vector<std::thread> thds;
int n_copier = 6;
double s = time_now();
mthd_memcpy(dst_buf, src_buf, buf_size, n_copier);
double e = time_now();
std::cout << "dur :" << e - s <<"\n";
std::cout << "bw :" << (buf_size * 8 / (e - s) ) / 1e9 << " Gbps\n";
bool v = verify_value(src_buf, dst_buf, buf_size);
if (v)
std::cout << "verify data passed\n";
else
std::cout << "verify failed\n";
delete[] src_buf;
delete[] dst_buf;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment