1. We use FIO and set the engine to be libpmem to randomly read a file in ext4-dax file system. The pcm tools show that the pmem read bandwidth is about 4.9GB/s.
2. However, we write another simple test demo to mmap the pmem file and start several threads to send the random read quests, it shows only about 2.9GB/s for one PM device.
We want to know why we can not reach the 4.9GB/s for random read requests, just as FIO did. The read size is 4KB for one read request.
-------------------------------------------------------------------------------------------
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#ifndef _WIN32
#include <unistd.h>
#else
#include <io.h>
#endif
#include <string.h>
#include <libpmem.h>
#include <pthread.h>
#define BUF_LEN 4096
char buf[20][BUF_LEN];
char *pmemaddr;
size_t mapped_len;
static void* fn(void *arg)
{
int i = *(int *)arg;
int offset = 0;
long total = 1024*1024*100;
printf("I am in thread %d!\n", i);
for (long m = 0; m < total; ++m) {
offset = rand() % (mapped_len-BUF_LEN);
memcpy(buf[i], pmemaddr+offset, BUF_LEN);
if (m % 10240 == 0) {
//printf("offset: %d, thread %d, %d * 4k\n", offset, i, m);
}
}
printf("I am in thread %d Finished...!\n", i);
return NULL;
}
int
main(int argc, char *argv[])
{
int srcfd;
int is_pmem;
int cc;
pthread_t threads[100];
int NUM_THREADS = 1;
if (argc < 2) {
fprintf(stderr, "usage: %s file num_threads \n", argv[0]);
exit(1);
}
if (argc >= 3) {
NUM_THREADS = atoi(argv[2]);
}
printf("Begin to open file: %s with %d threads\n", argv[1], NUM_THREADS);
/* create a pmem file and memory map it */
if ((pmemaddr = pmem_map_file(argv[1], 0, 0,
0666, &mapped_len, &is_pmem)) == NULL) {
perror("pmem_map_file");
exit(1);
}
printf("map file success, file: %s, size: %ld, is_pmem: %d\n", argv[1], mapped_len, is_pmem);
for (int i = 0; i < NUM_THREADS; ++i) {
pthread_create(threads+i, NULL, fn, &i);
}
printf("Waiting for the threads to finish...\n");
for (int i = 0; i < NUM_THREADS; ++i) {
pthread_join(threads[i], NULL);
}
printf("All Finished!\n");
return 0;
}