我正在为 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 获得真正的并行性吗?
您当然可以从不同的线程调用系统调用(列在syscalls(2) 中)(否则将无法编写在多个线程上执行 IO 的程序,就像大多数多线程 Web 服务器所做的那样)。
但是,某些ioctl
(或其他奇怪的系统调用)可能会阻塞或需要很长时间(几秒或十分之一秒)才能执行。举个很好的例子,弹出一个 CDROM 托盘是由一些人完成的ioctl
,它需要一些可见的时间(可能是半秒)来执行(因为它是一些机械动作)。
我猜NVME跟SSD技术有关,有些操作很慢(因为硬件本身很慢)。您的瓶颈可能是硬件本身,那么任何类型的并行化都无济于事。它可能会发生 - 我真的不知道 - 您可能会ioctl
在多个线程中使用相同的(在同一个文件描述符上)但内核会序列化其处理。
当内核执行一些阻塞或长时间运行ioctl
(或任何其他系统调用)时,它使用其调度程序来运行其他任务(进程或线程)并进行一些锁定。然后您的进程处于一种D
状态(参见proc(5)和//proc/self/stat
或/proc/1234/stat
pid 1234 的进程)并且甚至不处理被推迟的信号(参见signal(7))。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句