我正在研究nvme-cli的测试工具(用c编写,可以在linux上运行)。
我有兴趣用't'个线程重复nvme命令'r'次。
下面的代码重复执行每个命令以及线程,但问题是并行执行时间与串行执行相比非常高。
我找到的原因是
err = nvme_identify(fd, 0, 1, data);
转而调用系统调用ioctl();
#pragma omp parallel for num_threads(5)
for(i=0; i<rc; i++){
err = nvme_identify(fd, 0, 1, data);
if (!err) {
if (rf->fmt == BINARY)
d_raw((unsigned char *)&rf->ctrl, sizeof(rf->ctrl));
else if (rf->fmt == JSON)
json_nvme_id_ctrl(data, flags, 0);
else {
printf("NVME Identify Controller:\n");
__show_nvme_id_ctrl(data, flags, 0);
}
}
else if (err > 0)
fprintf(stderr, "NVMe Status:%s(%x)\n",
nvme_status_to_string(err), err);
else
perror("identify controller");
所以我可以知道如何使用openmp或pthreads获得真正的并行性吗?
答案 0 :(得分:1)
你当然可以从不同的线程调用system calls(在syscalls(2)中列出)(否则就不可能编写在多个线程上执行IO的程序,就像大多数多线程Web服务器一样)。
但是,某些ioctl
(或其他奇怪的系统调用)可能会阻塞或需要很长时间(几秒或十分之几秒)才能执行。举个好例子,弹出一个CDROM托盘由一些ioctl
完成,它需要一些可见的时间(可能是半秒)才能完成(因为这是一些机械动作)。
我猜NVME与SSD技术有关,有些操作很慢(因为硬件本身很慢)。您的瓶颈可能是硬件本身,然后任何类型的并行化都无济于事。它可能发生 - 我真的不知道 - 您可能在多个线程中使用相同的ioctl
(在相同的文件描述符上),但内核将序列化其处理。
当内核执行某些阻塞或长时间运行的ioctl
(或任何其他系统调用)时,它使用其调度程序来运行其他任务(进程或线程)并执行一些locking。然后,您的流程处于D
状态(请参阅proc(5)和/proc/self/stat
或/proc/1234/stat
了解pid 1234的过程),甚至不处理信号(请参阅{{3} })推迟了。