История изменений
Исправление
kilokolyan,
(текущая версия)
:
Про стек - да. Во многих случаях так.
Про копирование. Замерял тут время работы ::read()
внезапно.
Код получения текущего времени:
uint64_t curr_nano_mono() {
timespec ts;
if (!clock_gettime(CLOCK_MONOTONIC, &ts)) {
return ts.tv_sec * 1000000000L + ts.tv_nsec;
}
return 0;
}
Мерял так:
auto t1 = curr_nano_mono();
int rd = ::read(socket, ptr, size);
auto t2 = curr_nano_mono();
printf("read time %lu ns\n", t2 - t1);
И получилось такое:
// браузер присылает нам по websocket короткие посылки с интервалом в секунду примерно
1 read time 26576 ns
2 read time 23573 ns
3 read time 23166 ns
4 read time 19196 ns
5 read time 16056 ns
6 read time 22784 ns
7 read time 18044 ns
8 read time 23853 ns
9 read time 24285 ns
10 read time 18270 ns
11 // брайзер начал посылать посылки чуть длиннее и сильно часто: read стал возвращаться быстрее (видимо что-то прогрето)
12 read time 7085 ns
13 read time 3573 ns
14 read time 3815 ns
15 read time 4042 ns
16 read time 3456 ns
17 read time 3815 ns
18 read time 6751 ns
19 read time 12444 ns
20 read time 9010 ns
21 read time 23797 ns
22 // браузер снова начал слать что-то мелкое раз в секунду (байт 16 payload) как в начале
23 read time 18039 ns
24 read time 15884 ns
25 read time 19076 ns
26 read time 18059 ns
27 read time 22291 ns
28 read time 18965 ns
29 read time 17606 ns
30 read time 17034 ns
31 read time 16870 ns
32 read time 12785 ns
33 read time 23127 ns
34 read time 17811 ns
35 read time 18065 ns
36 read time 17959 ns
Потом померял сколько у меня выжимает memcpy()
вот таким методом. Возможно метод дебилен:
#include <iostream>
#include <vector>
#include <string.h>
uint64_t curr_nano_mono() {
timespec ts;
if (!clock_gettime(CLOCK_MONOTONIC, &ts)) {
return ts.tv_sec * 1000000000L + ts.tv_nsec;
}
return 0;
}
struct Measure {
uint64_t start_{};
const char *name_{};
explicit Measure(const char *_name)
: start_(curr_nano_mono())
, name_(_name)
{
}
uint64_t elapsed() {
return curr_nano_mono() - start_;
}
~Measure() {
printf("%s: %lu ns\n", name_, elapsed());
}
};
int main() {
const auto BUFFS = 32;
const auto BS = 1024 * 1024 * 8;
std::vector<char*> vect(BUFFS, nullptr);
srand(time(nullptr));
{
Measure me("alloc");
for (auto &p : vect) {
p = new char[BS];
}
}
{
Measure me("fill");
for (auto &buff : vect) {
for (char *p = buff, *end = buff + BS; p < end; ++p) {
*p = reinterpret_cast<size_t>(p) % 256;
}
}
}
{
Measure me("copy");
const auto ITERS = 1024;
size_t bytes = 0;
// Copy some bytes from random "from" to random "to" with random offset in "from".
for (auto iter = ITERS; iter >= 0; --iter) {
auto from = 0;
auto to = 0;
// this loop makes sure we use different buffers
while (from == to) {
from = rand() % BUFFS;
to = rand() % BUFFS;
}
// small random offset
auto offset = rand() % (1024*16);
bytes += (BS - offset);
::memcpy(vect[to], vect[from] + offset, BS - offset);
}
auto elapsed = me.elapsed();
double seconds = static_cast<double>(elapsed) / 1000000000.0;
double cost = ((1024.0 * 1024.0) / (double)bytes);
printf("Memcpy %.2lf byte/sec, took %.2lf sec, %lu ns\n", bytes / seconds, seconds, elapsed);
printf("1MB copy time cost: %.2lf ns\n", elapsed * cost);
}
return 0;
}
Собрать и запустить так:
rm a.out; g++ -std=c++11 -O3 memcpy-measure.cpp; ./a.out
И на моём lenovo carbon X1 gen 7 получил такое:
alloc: 53937 ns
fill: 769249218 ns
Memcpy 10147233381.31 byte/sec, took 0.85 sec, 846528728 ns
1MB copy time cost: 103336.15 ns
copy: 846548979 ns
Железо ноута:
i7-8565U
Type: LPDDR3
Type Detail: Synchronous
Speed: 2133 MT/s
Отсюда 1MB copy time cost: 103336.15 ns
и из времени syscall ::read()
в районе 5-25 ns
можно сказать, что syscall мне сильно дешевле, чем мегабайт памяти копировать. Т.е. если у меня в сокет не влез мегабайт, то мне проще подарить указатель на буфер сетевой подсистеме и забыть, чем копировать.
Исправление
kilokolyan,
:
Про стек - да. Во многих случаях так.
Про копирование. Замерял тут время работы ::read()
внезапно.
Код получения текущего времени:
uint64_t curr_nano_mono() {
timespec ts;
if (!clock_gettime(CLOCK_MONOTONIC, &ts)) {
return ts.tv_sec * 1000000000L + ts.tv_nsec;
}
return 0;
}
Мерял так:
auto t1 = curr_nano_mono();
int rd = ::read(socket, ptr, size);
auto t2 = curr_nano_mono();
printf("read time %lu ns\n", t2 - t1);
И получилось такое:
// браузер присылает нам по websocket короткие посылки с интервалом в секунду примерно
1 read time 26576 ns
2 read time 23573 ns
3 read time 23166 ns
4 read time 19196 ns
5 read time 16056 ns
6 read time 22784 ns
7 read time 18044 ns
8 read time 23853 ns
9 read time 24285 ns
10 read time 18270 ns
11 // брайзер начал посылать посылки чуть длиннее и сильно часто: read стал возвращаться быстрее (видимо что-то прогрето)
12 read time 7085 ns
13 read time 3573 ns
14 read time 3815 ns
15 read time 4042 ns
16 read time 3456 ns
17 read time 3815 ns
18 read time 6751 ns
19 read time 12444 ns
20 read time 9010 ns
21 read time 23797 ns
22 // браузер снова начал слать что-то мелкое раз в секунду (байт 16 payload) как в начале
23 read time 18039 ns
24 read time 15884 ns
25 read time 19076 ns
26 read time 18059 ns
27 read time 22291 ns
28 read time 18965 ns
29 read time 17606 ns
30 read time 17034 ns
31 read time 16870 ns
32 read time 12785 ns
33 read time 23127 ns
34 read time 17811 ns
35 read time 18065 ns
36 read time 17959 ns
Потом померял сколько у меня выжимает memcpy()
вот таким методом. Возможно метод дебилен:
#include <iostream>
#include <vector>
#include <string.h>
uint64_t curr_nano_mono() {
timespec ts;
if (!clock_gettime(CLOCK_MONOTONIC, &ts)) {
return ts.tv_sec * 1000000000L + ts.tv_nsec;
}
return 0;
}
struct Measure {
uint64_t start_{};
const char *name_{};
explicit Measure(const char *_name)
: start_(curr_nano_mono())
, name_(_name)
{
}
uint64_t elapsed() {
return curr_nano_mono() - start_;
}
~Measure() {
printf("%s: %lu ns\n", name_, elapsed());
}
};
int main() {
const auto BUFFS = 32;
const auto BS = 1024 * 1024 * 8;
std::vector<char*> vect(BUFFS, nullptr);
srand(time(nullptr));
{
Measure me("alloc");
for (auto &p : vect) {
p = new char[BS];
}
}
{
Measure me("fill");
for (auto &buff : vect) {
for (char *p = buff, *end = buff + BS; p < end; ++p) {
*p = reinterpret_cast<size_t>(p) % 256;
}
}
}
{
Measure me("copy");
const auto ITERS = 1024;
size_t bytes = 0;
// Copy some bytes from random "from" to random "to" with random offset in "from".
for (auto iter = ITERS; iter >= 0; --iter) {
auto from = 0;
auto to = 0;
// this loop makes sure we use different buffers
while (from == to) {
from = rand() % BUFFS;
to = rand() % BUFFS;
}
// small random offset
auto offset = rand() % (1024*16);
bytes += (BS - offset);
::memcpy(vect[to], vect[from] + offset, BS - offset);
}
auto elapsed = me.elapsed();
double seconds = static_cast<double>(elapsed) / 1000000000.0;
double cost = ((1024.0 * 1024.0) / (double)bytes);
printf("Memcpy %.2lf byte/sec, took %.2lf sec, %lu ns\n", bytes / seconds, seconds, elapsed);
printf("1MB copy time cost: %.2lf ns\n", elapsed * cost);
}
return 0;
}
Собрать и запустить так:
rm a.out; g++ -std=c++11 -O3 memcpy-measure.cpp; ./a.out
И на моём lenovo carbon X1 gen 7 получил такое:
alloc: 53937 ns
fill: 769249218 ns
Memcpy 10147233381.31 byte/sec, took 0.85 sec, 846528728 ns
1MB copy time cost: 103336.15 ns
copy: 846548979 ns
Железо ноута:
i7-8565U
Type: LPDDR3
Type Detail: Synchronous
Speed: 2133 MT/s
Отсюда можно сказать, что syscall мне сильно дешевле, чем мегабайт памяти копировать. Т.е. если у меня в сокет не влез мегабайт, то мне проще подарить указатель на буфер сетевой подсистеме и забыть, чем копировать.
Исправление
kilokolyan,
:
Про стек - да. Во многих случаях так.
Про копирование. Замерял тут время работы ::read()
внезапно.
Код получения текущего времени:
uint64_t curr_nano_mono() {
timespec ts;
if (!clock_gettime(CLOCK_MONOTONIC, &ts)) {
return ts.tv_sec * 1000000000L + ts.tv_nsec;
}
return 0;
}
Мерял так:
auto t1 = curr_nano_mono();
int rd = ::read(socket, ptr, size);
auto t2 = curr_nano_mono();
printf("read time %lu ns\n", t2 - t1);
И получилось такое:
// браузер присылает нам по websocket короткие посылки с интервалом в секунду примерно
1 read time 26576 ns
2 read time 23573 ns
3 read time 23166 ns
4 read time 19196 ns
5 read time 16056 ns
6 read time 22784 ns
7 read time 18044 ns
8 read time 23853 ns
9 read time 24285 ns
10 read time 18270 ns
11 // брайзер начал посылать посылки чуть длиннее и сильно часто: read стал возвращаться быстрее (видимо что-то прогрето)
12 read time 7085 ns
13 read time 3573 ns
14 read time 3815 ns
15 read time 4042 ns
16 read time 3456 ns
17 read time 3815 ns
18 read time 6751 ns
19 read time 12444 ns
20 read time 9010 ns
21 read time 23797 ns
22 // браузер снова начал слать что-то мелкое раз в секунду (байт 16 payload) как в начале
23 read time 18039 ns
24 read time 15884 ns
25 read time 19076 ns
26 read time 18059 ns
27 read time 22291 ns
28 read time 18965 ns
29 read time 17606 ns
30 read time 17034 ns
31 read time 16870 ns
32 read time 12785 ns
33 read time 23127 ns
34 read time 17811 ns
35 read time 18065 ns
36 read time 17959 ns
Потом померял сколько у меня выжимает memcpy()
вот таким методом. Возможно метод дебилен:
#include <iostream>
#include <vector>
#include <string.h>
uint64_t curr_nano_mono() {
timespec ts;
if (!clock_gettime(CLOCK_MONOTONIC, &ts)) {
return ts.tv_sec * 1000000000L + ts.tv_nsec;
}
return 0;
}
struct Measure {
uint64_t start_{};
const char *name_{};
explicit Measure(const char *_name)
: start_(curr_nano_mono())
, name_(_name)
{
}
uint64_t elapsed() {
return curr_nano_mono() - start_;
}
~Measure() {
printf("%s: %lu ns\n", name_, elapsed());
}
};
int main() {
const auto BUFFS = 32;
const auto BS = 1024 * 1024 * 8;
std::vector<char*> vect(BUFFS, nullptr);
srand(time(nullptr));
{
Measure me("alloc");
for (auto &p : vect) {
p = new char[BS];
}
}
{
Measure me("fill");
for (auto &buff : vect) {
for (char *p = buff, *end = buff + BS; p < end; ++p) {
*p = reinterpret_cast<size_t>(p) % 256;
}
}
}
{
Measure me("copy");
const auto ITERS = 1024;
size_t bytes = 0;
// Copy some bytes from random "from" to random "to" with random offset in "from".
for (auto iter = ITERS; iter >= 0; --iter) {
auto from = 0;
auto to = 0;
// this loop makes sure we use different buffers
while (from == to) {
from = rand() % BUFFS;
to = rand() % BUFFS;
}
// small random offset
auto offset = rand() % (1024*16);
bytes += (BS - offset);
::memcpy(vect[to], vect[from] + offset, BS - offset);
}
auto elapsed = me.elapsed();
double seconds = static_cast<double>(elapsed) / 1000000000.0;
double cost = ((1024.0 * 1024.0) / (double)bytes);
printf("Memcpy %.2lf byte/sec, took %.2lf sec, %lu ns\n", bytes / seconds, seconds, elapsed);
printf("1MB copy time cost: %.2lf ns\n", elapsed * cost);
}
return 0;
}
Собрать и запустить так:
rm a.out; g++ -std=c++11 -O3 memcpy-measure.cpp; ./a.out
И на моём lenovo carbon X1 gen 7 получил такое:
alloc: 53937 ns
fill: 769249218 ns
Memcpy 10147233381.31 byte/sec, took 0.85 sec, 846528728 ns
1MB copy time cost: 103336.15 ns
copy: 846548979 ns
Железо ноута:
i7-8565U
Type: LPDDR3
Type Detail: Synchronous
Speed: 2133 MT/s
Исправление
kilokolyan,
:
Про стек - да. Во многих случаях так.
Про копирование. Замерял тут время работы ::read()
внезапно.
Код получения текущего времени:
uint64_t curr_nano_mono() {
timespec ts;
if (!clock_gettime(CLOCK_MONOTONIC, &ts)) {
return ts.tv_sec * 1000000000L + ts.tv_nsec;
}
return 0;
}
Мерял так:
auto t1 = curr_nano_mono();
int rd = ::read(socket, ptr, size);
auto t2 = curr_nano_mono();
printf("read time %lu ns\n", t2 - t1);
И получилось такое:
// браузер присылает нам по websocket короткие посылки с интервалом в секунду примерно
1 read time 26576 ns
2 read time 23573 ns
3 read time 23166 ns
4 read time 19196 ns
5 read time 16056 ns
6 read time 22784 ns
7 read time 18044 ns
8 read time 23853 ns
9 read time 24285 ns
10 read time 18270 ns
11 // брайзер начал посылать посылки чуть длиннее и сильно часто: read стал возвращаться быстрее (видимо что-то прогрето)
12 read time 7085 ns
13 read time 3573 ns
14 read time 3815 ns
15 read time 4042 ns
16 read time 3456 ns
17 read time 3815 ns
18 read time 6751 ns
19 read time 12444 ns
20 read time 9010 ns
21 read time 23797 ns
22 // браузер снова начал слать что-то мелкое (байт 16 payload) в секунду.
23 read time 18039 ns
24 read time 15884 ns
25 read time 19076 ns
26 read time 18059 ns
27 read time 22291 ns
28 read time 18965 ns
29 read time 17606 ns
30 read time 17034 ns
31 read time 16870 ns
32 read time 12785 ns
33 read time 23127 ns
34 read time 17811 ns
35 read time 18065 ns
36 read time 17959 ns
Потом померял сколько у меня выжимает memcpy()
вот таким методом. Возможно метод дебилен:
#include <iostream>
#include <vector>
#include <string.h>
uint64_t curr_nano_mono() {
timespec ts;
if (!clock_gettime(CLOCK_MONOTONIC, &ts)) {
return ts.tv_sec * 1000000000L + ts.tv_nsec;
}
return 0;
}
struct Measure {
uint64_t start_{};
const char *name_{};
explicit Measure(const char *_name)
: start_(curr_nano_mono())
, name_(_name)
{
}
uint64_t elapsed() {
return curr_nano_mono() - start_;
}
~Measure() {
printf("%s: %lu ns\n", name_, elapsed());
}
};
int main() {
const auto BUFFS = 32;
const auto BS = 1024 * 1024 * 8;
std::vector<char*> vect(BUFFS, nullptr);
srand(time(nullptr));
{
Measure me("alloc");
for (auto &p : vect) {
p = new char[BS];
}
}
{
Measure me("fill");
for (auto &buff : vect) {
for (char *p = buff, *end = buff + BS; p < end; ++p) {
*p = reinterpret_cast<size_t>(p) % 256;
}
}
}
{
Measure me("copy");
const auto ITERS = 1024;
size_t bytes = 0;
// Copy some bytes from random "from" to random "to" with random offset in "from".
for (auto iter = ITERS; iter >= 0; --iter) {
auto from = 0;
auto to = 0;
// this loop makes sure we use different buffers
while (from == to) {
from = rand() % BUFFS;
to = rand() % BUFFS;
}
// small random offset
auto offset = rand() % (1024*16);
bytes += (BS - offset);
::memcpy(vect[to], vect[from] + offset, BS - offset);
}
auto elapsed = me.elapsed();
double seconds = static_cast<double>(elapsed) / 1000000000.0;
double cost = ((1024.0 * 1024.0) / (double)bytes);
printf("Memcpy %.2lf byte/sec, took %.2lf sec, %lu ns\n", bytes / seconds, seconds, elapsed);
printf("1MB copy time cost: %.2lf ns\n", elapsed * cost);
}
return 0;
}
Собрать и запустить так:
rm a.out; g++ -std=c++11 -O3 memcpy-measure.cpp; ./a.out
И на моём lenovo carbon X1 gen 7 получил такое:
alloc: 53937 ns
fill: 769249218 ns
Memcpy 10147233381.31 byte/sec, took 0.85 sec, 846528728 ns
1MB copy time cost: 103336.15 ns
copy: 846548979 ns
Железо ноута:
i7-8565U
Type: LPDDR3
Type Detail: Synchronous
Speed: 2133 MT/s
Исправление
kilokolyan,
:
Про стек - да. Во многих случаях так.
Про копирование. Замерял тут время работы ::read()
внезапно.
Код получения текущего времени:
uint64_t curr_nano_mono() {
timespec ts;
if (!clock_gettime(CLOCK_MONOTONIC, &ts)) {
return ts.tv_sec * 1000000000L + ts.tv_nsec;
}
return 0;
}
Мерял так:
auto t1 = curr_nano_mono();
int rd = ::read(socket, ptr, size);
auto t2 = curr_nano_mono();
printf("read time %lu ns\n", t2 - t1);
И получилось такое:
1 read time 26576 ns
2 read time 23573 ns
3 read time 23166 ns
4 read time 19196 ns
5 read time 16056 ns
6 read time 22784 ns
7 read time 18044 ns
8 read time 23853 ns
9 read time 24285 ns
10 read time 18270 ns
11 // брайзер начал посылать посылки чуть длиннее и сильно часто: read стал возвращаться быстрее (видимо что-то прогрето)
12 read time 7085 ns
13 read time 3573 ns
14 read time 3815 ns
15 read time 4042 ns
16 read time 3456 ns
17 read time 3815 ns
18 read time 6751 ns
19 read time 12444 ns
20 read time 9010 ns
21 read time 23797 ns
22 // браузер снова начал слать что-то мелкое (байт 16 payload) в секунду.
23 read time 18039 ns
24 read time 15884 ns
25 read time 19076 ns
26 read time 18059 ns
27 read time 22291 ns
28 read time 18965 ns
29 read time 17606 ns
30 read time 17034 ns
31 read time 16870 ns
32 read time 12785 ns
33 read time 23127 ns
34 read time 17811 ns
35 read time 18065 ns
36 read time 17959 ns
Потом померял сколько у меня выжимает memcpy()
вот таким методом. Возможно метод дебилен:
#include <iostream>
#include <vector>
#include <string.h>
uint64_t curr_nano_mono() {
timespec ts;
if (!clock_gettime(CLOCK_MONOTONIC, &ts)) {
return ts.tv_sec * 1000000000L + ts.tv_nsec;
}
return 0;
}
struct Measure {
uint64_t start_{};
const char *name_{};
explicit Measure(const char *_name)
: start_(curr_nano_mono())
, name_(_name)
{
}
uint64_t elapsed() {
return curr_nano_mono() - start_;
}
~Measure() {
printf("%s: %lu ns\n", name_, elapsed());
}
};
int main() {
const auto BUFFS = 32;
const auto BS = 1024 * 1024 * 8;
std::vector<char*> vect(BUFFS, nullptr);
srand(time(nullptr));
{
Measure me("alloc");
for (auto &p : vect) {
p = new char[BS];
}
}
{
Measure me("fill");
for (auto &buff : vect) {
for (char *p = buff, *end = buff + BS; p < end; ++p) {
*p = reinterpret_cast<size_t>(p) % 256;
}
}
}
{
Measure me("copy");
const auto ITERS = 1024;
size_t bytes = 0;
// Copy some bytes from random "from" to random "to" with random offset in "from".
for (auto iter = ITERS; iter >= 0; --iter) {
auto from = 0;
auto to = 0;
// this loop makes sure we use different buffers
while (from == to) {
from = rand() % BUFFS;
to = rand() % BUFFS;
}
// small random offset
auto offset = rand() % (1024*16);
bytes += (BS - offset);
::memcpy(vect[to], vect[from] + offset, BS - offset);
}
auto elapsed = me.elapsed();
double seconds = static_cast<double>(elapsed) / 1000000000.0;
double cost = ((1024.0 * 1024.0) / (double)bytes);
printf("Memcpy %.2lf byte/sec, took %.2lf sec, %lu ns\n", bytes / seconds, seconds, elapsed);
printf("1MB copy time cost: %.2lf ns\n", elapsed * cost);
}
return 0;
}
Собрать и запустить так:
rm a.out; g++ -std=c++11 -O3 memcpy-measure.cpp; ./a.out
И на моём lenovo carbon X1 gen 7 получил такое:
alloc: 53937 ns
fill: 769249218 ns
Memcpy 10147233381.31 byte/sec, took 0.85 sec, 846528728 ns
1MB copy time cost: 103336.15 ns
copy: 846548979 ns
Железо ноута:
i7-8565U
Type: LPDDR3
Type Detail: Synchronous
Speed: 2133 MT/s
Исходная версия
kilokolyan,
:
Про стек - да. Во многих случаях так.
Про копирование. Замерял тут время работы ::read
внезапно.
Код получения текущего времени:
uint64_t curr_nano_mono() {
timespec ts;
if (!clock_gettime(CLOCK_MONOTONIC, &ts)) {
return ts.tv_sec * 1000000000L + ts.tv_nsec;
}
return 0;
}
Мерял так:
auto t1 = curr_nano_mono();
int rd = ::read(socket, ptr, size);
auto t2 = curr_nano_mono();
printf("read time %lu ns\n", t2 - t1);
И получилось такое:
1 read time 26576 ns
2 read time 23573 ns
3 read time 23166 ns
4 read time 19196 ns
5 read time 16056 ns
6 read time 22784 ns
7 read time 18044 ns
8 read time 23853 ns
9 read time 24285 ns
10 read time 18270 ns
11 // брайзер начал посылать посылки чуть длиннее и сильно часто: read стал возвращаться быстрее (видимо что-то прогрето)
12 read time 7085 ns
13 read time 3573 ns
14 read time 3815 ns
15 read time 4042 ns
16 read time 3456 ns
17 read time 3815 ns
18 read time 6751 ns
19 read time 12444 ns
20 read time 9010 ns
21 read time 23797 ns
22 // браузер снова начал слать что-то мелкое (байт 16 payload) в секунду.
23 read time 18039 ns
24 read time 15884 ns
25 read time 19076 ns
26 read time 18059 ns
27 read time 22291 ns
28 read time 18965 ns
29 read time 17606 ns
30 read time 17034 ns
31 read time 16870 ns
32 read time 12785 ns
33 read time 23127 ns
34 read time 17811 ns
35 read time 18065 ns
36 read time 17959 ns
Потом померял сколько у меня выжимает memcpy()
вот таким методом. Возможно метод дебилен:
#include <iostream>
#include <vector>
#include <string.h>
uint64_t curr_nano_mono() {
timespec ts;
if (!clock_gettime(CLOCK_MONOTONIC, &ts)) {
return ts.tv_sec * 1000000000L + ts.tv_nsec;
}
return 0;
}
struct Measure {
uint64_t start_{};
const char *name_{};
explicit Measure(const char *_name)
: start_(curr_nano_mono())
, name_(_name)
{
}
uint64_t elapsed() {
return curr_nano_mono() - start_;
}
~Measure() {
printf("%s: %lu ns\n", name_, elapsed());
}
};
int main() {
const auto BUFFS = 32;
const auto BS = 1024 * 1024 * 8;
std::vector<char*> vect(BUFFS, nullptr);
srand(time(nullptr));
{
Measure me("alloc");
for (auto &p : vect) {
p = new char[BS];
}
}
{
Measure me("fill");
for (auto &buff : vect) {
for (char *p = buff, *end = buff + BS; p < end; ++p) {
*p = reinterpret_cast<size_t>(p) % 256;
}
}
}
{
Measure me("copy");
const auto ITERS = 1024;
size_t bytes = 0;
// Copy some bytes from random "from" to random "to" with random offset in "from".
for (auto iter = ITERS; iter >= 0; --iter) {
auto from = 0;
auto to = 0;
// this loop makes sure we use different buffers
while (from == to) {
from = rand() % BUFFS;
to = rand() % BUFFS;
}
// small random offset
auto offset = rand() % (1024*16);
bytes += (BS - offset);
::memcpy(vect[to], vect[from] + offset, BS - offset);
}
auto elapsed = me.elapsed();
double seconds = static_cast<double>(elapsed) / 1000000000.0;
double cost = ((1024.0 * 1024.0) / (double)bytes);
printf("Memcpy %.2lf byte/sec, took %.2lf sec, %lu ns\n", bytes / seconds, seconds, elapsed);
printf("1MB copy time cost: %.2lf ns\n", elapsed * cost);
}
return 0;
}
Собрать и запустить так:
rm a.out; g++ -std=c++11 -O3 memcpy-measure.cpp; ./a.out
И на моём lenovo carbon X1 gen 7 получил такое:
alloc: 53937 ns
fill: 769249218 ns
Memcpy 10147233381.31 byte/sec, took 0.85 sec, 846528728 ns
1MB copy time cost: 103336.15 ns
copy: 846548979 ns
Железо ноута:
i7-8565U
Type: LPDDR3
Type Detail: Synchronous
Speed: 2133 MT/s