我可以使用openmp或pthreads使用不同的线程调用相同的系统调用

时间:2017-11-21 06:39:29

标签: c multithreading pthreads openmp systems-programming

我正在研究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获得真正的并行性吗?

1 个答案:

答案 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} })推迟了。