Python 在使用mutliprocessing时,如何达到100%的CPU利用率?

Python 在使用mutliprocessing时,如何达到100%的CPU利用率?,python,linux,optimization,multiprocessing,cpu-usage,Python,Linux,Optimization,Multiprocessing,Cpu Usage,我试图通过同时运行4个进程来使用多处理来加速我的python3脚本。然而,我的进程从未达到100%的CPU利用率。我的代码的核心只是读取.mp3录音,并使用scikit learn对其进行识别,然后将结果保存到.json中 这是我的顶部输出: top - 17:07:07 up 18 days, 3:31, 4 users, load average: 3.73, 3.67, 3.87 Tasks: 137 total, 1 running, 75 sleeping, 18 sto

我试图通过同时运行4个进程来使用多处理来加速我的python3脚本。然而,我的进程从未达到100%的CPU利用率。我的代码的核心只是读取
.mp3
录音,并使用
scikit learn
对其进行识别,然后将结果保存到
.json

这是我的
顶部
输出:

top - 17:07:07 up 18 days,  3:31,  4 users,  load average: 3.73, 3.67, 3.87
Tasks: 137 total,   1 running,  75 sleeping,  18 stopped,   0 zombie
%Cpu(s): 32.8 us, 20.3 sy,  0.0 ni, 46.3 id,  0.0 wa,  0.0 hi,  0.5 si,  0.1 st
KiB Mem :  8167880 total,  2683088 free,  4314756 used,  1170036 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  3564064 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                           
 5832 am        20   0 1887644 776736  24076 S  63.0  9.5 201:10.19 python3                                                           
 5829 am        20   0 1956336 845556  24348 S  55.0 10.4 200:31.20 python3                                                           
 5830 am        20   0 2000772 890260  23820 S  55.0 10.9 200:39.80 python3                                                           
 5834 am        20   0 2430932 1.260g  24252 S  50.3 16.2 200:45.52 python3                                                           
 4657 am        20   0  108116   4460   3424 S   0.3  0.1   1:11.48 sshd                                                              
 6564 root      20   0       0      0      0 I   0.3  0.0   7:30.08 kworker/2:1                                                       
    1 root      20   0  225212   6660   4452 S   0.0  0.1   0:26.33 systemd                                                           
......
正如您在前面的输出中所看到的,内存上没有重载,因此有限的CPU利用率与I/O或内存无关

是否有办法“强制”python使用所有100%的资源?或者,我如何调试代码以找出导致这种情况的原因?如果我遗漏了一些明显的东西,如何更改代码以达到100%的CPU利用率?

下面是我的主要多处理代码的一个小概述:

# -*- coding: utf-8 -*-
import os
import time
import logging
import cProfile
import multiprocessing as mp
from packages.Recognizer import Recognizer
from packages.RecordingFile import RecordingFile
from packages.utils.pickle_utils import pickle_load

_PRINTS = True


class ServerSER:

    def __init__(self, date, model_fname, results_path,
                 nprocs=1, run_type="server"):
       # bunch of inits


    def process_files(self):
        # Setup a list of processes that we want to run
        self.processes = [mp.Process(target=self.recognition_func, args=("processes/p" + str(p),
                                     self.model_obj, p, self.output))
                          for p in range(self.nprocs)]
        # Run processes
        for p in self.processes: p.start()

        # Exit the completed processes
        for p in self.processes: p.join()

        # Get process results from the output queue
        self.results = []
        for p in self.processes:
            try:
                r = self.output.get_nowait()
                self.results.append(r)
            except Exception as e:
                print(e)

        return [e[1][0] for e in self.results]


    def recognition_func(self, pfolder, model_obj, pos, output, profile=True):
        # start profiling
        pr = cProfile.Profile()
        pr.enable()

        # start logging
        logger_name = "my-logger" + str(pos)
        logging.basicConfig(format='%(asctime)s  %(levelname)5s  %(message)s',
                            level=logging.INFO, filename=logger_name + ".txt")
        logging.info("Start logging for process number " + str(pos))

        # start processing until no files available
        while len([f for f in os.listdir(pfolder) if ".mp3" in f]) > 0: 
            # get oldest file
            oldest_file = [f for f in self.sorted_ls(pfolder) if ".mp3" in f][0]

            # process
            try: 
                recording = RecordingFile(pfolder=pfolder,
                                          base_url=self.base_url,
                                          fpath=oldest_file,
                                          results_path=self.results_path)

                if _PRINTS:
                    msg = "%10s : %50s" % ("PROCESSING", oldest_file)
                    logging.info(msg)

                    # prints
                    print("------------------------------------------------------------------------")
                    print("%10s : %50s" % ("PROCESSING", oldest_file))
                    print("------------------------------------------------------------------------")

                # recognize for file
                _ = Recognizer(recording=recording,
                               duration_step=1,
                               channel=1,
                               model_obj=self.model_obj)

                # clean ups
                recording.delete_files()
                print("%10s." % ("DONE"))
                print("------------------------------------------------------------------------")

            except Exception as e:
                self.errors[oldest_file] = e
                logging.warn(e)
                print(e, " while processing ", oldest_file)

        # put results in queue
        self.output.put((pos, [self.errors, self.durations]))

        # save profiling results
        # pr.print_stats(sort='time')
        pr.disable()
        pr.dump_stats("incode_cprofiler_output" + str(pos) + ".txt")
        return True
uname-a的输出:
Linux 4.15.0-70-generic\79 Ubuntu SMP x86\U 64 x86\U 64 x86\U 64 GNU/Linux

lscpu的输出

Architecture:        x86_64
CPU op-mode(s):      32-bit, 64-bit
Byte Order:          Little Endian
CPU(s):              4
On-line CPU(s) list: 0-3
Thread(s) per core:  1
Core(s) per socket:  4
Socket(s):           1
NUMA node(s):        1
Vendor ID:           GenuineIntel
CPU family:          6
Model:               94
Model name:          Intel Core Processor (Skylake, IBRS)
Stepping:            3
CPU MHz:             3696.000
BogoMIPS:            7392.00
Virtualization:      VT-x
Hypervisor vendor:   KVM
Virtualization type: full
L1d cache:           32K
L1i cache:           32K
L2 cache:            4096K
L3 cache:            16384K
NUMA node0 CPU(s):   0-3
编辑

当对进程数进行一点调整时,会发生以下情况:

  • 在我使用1个进程的情况下,CPU使用率是110%
  • 对于2个进程,CPU使用率为80%
  • 对于6个进程,每个进程的CPU使用率约为50%

您为什么想要100%的折扣?测试目的或?充分利用我的cpu?目前每个核心平均只达到65%,这意味着它没有充分利用可用的计算能力。我不需要它总是100%,但如果它充分利用了cpu,它应该时不时地达到。Python没有限制cpu的使用,所以问题在于
self.recognition\u func
。它是磁盘密集型的吗?您可以看到它是如何在没有多处理的情况下连续工作的。比如说,你可以做6个作业,一次,然后看看cpu使用率是否上升。至少有一个或两个以上的内核(对于IO操作)是有用的。这是出乎意料的。它就像scikit在共享资源上陷入困境一样。scikit似乎不使用GPU(这是我最好的猜测)。但它确实使用python
joblib
来实现并行性。也许您应该研究scikit方式的多处理,而不是
多处理方法。也许有一些致命的拥抱在那里的某个地方,导致等待/超时。您希望在完全提交的服务器上看到平均负载超过100%(平均负载计算是一门黑暗的艺术)。为什么要100%呢?测试目的或?充分利用我的cpu?目前每个核心平均只达到65%,这意味着它没有充分利用可用的计算能力。我不需要它总是100%,但如果它充分利用了cpu,它应该时不时地达到。Python没有限制cpu的使用,所以问题在于
self.recognition\u func
。它是磁盘密集型的吗?您可以看到它是如何在没有多处理的情况下连续工作的。比如说,你可以做6个作业,一次,然后看看cpu使用率是否上升。至少有一个或两个以上的内核(对于IO操作)是有用的。这是出乎意料的。它就像scikit在共享资源上陷入困境一样。scikit似乎不使用GPU(这是我最好的猜测)。但它确实使用python
joblib
来实现并行性。也许您应该研究scikit方式的多处理,而不是
多处理方法。也许有一些致命的拥抱在那里的某个地方,导致等待/超时。您希望在完全提交的服务器上看到平均负载超过100%(平均负载计算是一门黑暗的艺术)。