Skip to content

Instantly share code, notes, and snippets.

@Gerold103
Created October 2, 2023 16:09
Show Gist options
  • Save Gerold103/edbc7edc75a492a64ade9b8e4898be02 to your computer and use it in GitHub Desktop.
Save Gerold103/edbc7edc75a492a64ade9b8e4898be02 to your computer and use it in GitHub Desktop.
BenchScatterGatherIO
#include <cassert>
#include <cstring>
#include <ctime>
#include <iostream>
#include <thread>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#define USE_VECTORS 1
static constexpr uint16_t port = 12345;
static constexpr int bufCount = 16;
static constexpr size_t bufSize = 1024;
static constexpr size_t totalBufSize = bufCount * bufSize;
static constexpr size_t totalToSend = 15ULL * 1024 * 1024 * 1024;
static uint64_t durationUsec = 0;
static uint64_t systemCallRecvCount = 0;
static uint64_t systemCallSendCount = 0;
static uint64_t getUsec()
{
timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
return t.tv_sec * 1'000'000 + t.tv_nsec / 1000;
}
static void doSending(int sock)
{
uint8_t *data = new uint8_t[totalBufSize];
memset(data, 0, totalBufSize);
size_t sent = 0;
struct iovec vecs[bufCount];
memset(vecs, 0, sizeof(vecs));
for (int i = 0; i < bufCount; ++i)
{
vecs[i].iov_base = data + bufSize * i;
vecs[i].iov_len = bufSize;
}
#if USE_VECTORS
msghdr msg;
memset(&msg, 0, sizeof(msg));
msg.msg_iov = vecs;
msg.msg_iovlen = bufCount;
#endif
while (sent < totalToSend)
{
#if USE_VECTORS
++systemCallSendCount;
ssize_t rc = sendmsg(sock, &msg, 0);
assert(rc > 0);
sent += rc;
#else
for (int i = 0; i < bufCount && sent < totalToSend; ++i)
{
++systemCallSendCount;
ssize_t rc = send(sock, vecs[i].iov_base, vecs[i].iov_len, 0);
assert(rc > 0);
sent += rc;
}
#endif
}
delete[] data;
}
static void doReceving(int sock)
{
uint8_t *data = new uint8_t[totalBufSize];
memset(data, 0, totalBufSize);
size_t received = 0;
struct iovec vecs[bufCount];
memset(vecs, 0, sizeof(vecs));
for (int i = 0; i < bufCount; ++i)
{
vecs[i].iov_base = data + bufSize * i;
vecs[i].iov_len = bufSize;
}
#if USE_VECTORS
msghdr msg;
memset(&msg, 0, sizeof(msg));
msg.msg_iov = vecs;
msg.msg_iovlen = bufCount;
#endif
uint64_t t1 = getUsec();
while (received < totalToSend)
{
#if USE_VECTORS
++systemCallRecvCount;
ssize_t rc = recvmsg(sock, &msg, 0);
assert(rc > 0);
received += rc;
#else
for (int i = 0; i < bufCount && received < totalToSend; ++i)
{
++systemCallRecvCount;
ssize_t rc = recv(sock, vecs[i].iov_base, vecs[i].iov_len, 0);
assert(rc > 0);
received += rc;
}
#endif
}
durationUsec = getUsec() - t1;
delete[] data;
}
static void clientF()
{
std::cout << "Client is started" << std::endl;
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
int sock = socket(AF_INET, SOCK_STREAM, 0);
assert(sock >= 0);
int rc = connect(sock, (sockaddr *)&addr, sizeof(addr));
assert(rc == 0);
doReceving(sock);
close(sock);
std::cout << "Client is finished" << std::endl;
}
int main()
{
std::cout << "Server is started" << std::endl;
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
socklen_t len = sizeof(addr);
int sock = socket(AF_INET, SOCK_STREAM, 0);
assert(sock >= 0);
int value = 1;
int rc = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
assert(rc == 0);
rc = bind(sock, (sockaddr *)&addr, len);
assert(rc == 0);
rc = listen(sock, SOMAXCONN);
assert(rc == 0);
std::cout << "Receive the data" << std::endl;
std::thread clientThread(clientF);
int peer = accept(sock, (sockaddr *)&addr, &len);
assert(peer >= 0);
doSending(peer);
std::cout << "Terminate the client" << std::endl;
clientThread.join();
close(peer);
close(sock);
std::cout << "Took " << durationUsec << " us" << std::endl;
std::cout << "System calls recv(): " << systemCallRecvCount << std::endl;
std::cout << "System calls send(): " << systemCallSendCount << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment