Python多处理:限制使用的核心数

2024-04-19 11:28:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我想知道如何将N个独立任务分配给一台具有L核的计算机上的M个处理器,其中L>;M。我不想使用所有处理器,因为我仍然希望有可用的I/O。我尝试过的解决方案似乎被分发到所有处理器,使系统陷入困境。

我认为多处理模块是可行的。

我做数值模拟。我的背景是物理学,而不是计算机科学,所以不幸的是,我经常不完全理解有关标准任务模型(如服务器/客户机、生产者/消费者等)的讨论

以下是我尝试过的一些简化模型:

假设我有一个运行模拟的函数run_sim(**kwargs)(请看下面的内容),以及一长串用于模拟的kwargs,并且我有一个8核机器。

from multiprocessing import Pool, Process

#using pool
p = Pool(4)
p.map(run_sim, kwargs)

# using process
number_of_live_jobs=0
all_jobs=[]
sim_index=0
while sim_index < len(kwargs)+1:
   number_of_live_jobs = len([1 for job in all_jobs if job.is_alive()])
   if number_of_live_jobs <= 4:
      p = Process(target=run_sim, args=[], kwargs=kwargs[sim_index])
      print "starting job", kwargs[sim_index]["data_file_name"]
      print "number of live jobs: ", number_of_live_jobs
      p.start()
      p.join()
      all_jobs.append(p)
      sim_index += 1

当我用“top”和“1”来查看处理器的使用情况时,不管是哪种情况,所有的处理器似乎都会被使用。我误解了“top”的输出并不是不可能的,但是如果run_simulation()是处理器密集型的,那么机器就会严重陷入困境。

假设模拟和数据:

# simulation kwargs
numbers_of_steps = range(0,10000000, 1000000)
sigmas = [x for x in range(11)]
kwargs = []
for number_of_steps in numbers_of_steps:
   for sigma in sigmas:
      kwargs.append(
         dict(
            number_of_steps=number_of_steps,
            sigma=sigma,
            # why do I need to cast to int?
            data_file_name="walk_steps=%i_sigma=%i" % (number_of_steps, sigma),
            )
         )

import random, time
random.seed(time.time())

# simulation of random walk
def run_sim(kwargs):
   number_of_steps = kwargs["number_of_steps"]
   sigma = kwargs["sigma"]
   data_file_name = kwargs["data_file_name"]
   data_file = open(data_file_name+".dat", "w")
   current_position = 0
   print "running simulation", data_file_name
   for n in range(int(number_of_steps)+1):
      data_file.write("step number %i   position=%f\n" % (n, current_position))
      random_step = random.gauss(0,sigma)
      current_position += random_step

   data_file.close()

Tags: ofrunnamelivenumberdataindexjobs
3条回答

您可能需要查看以下包:

http://pypi.python.org/pypi/affinity

它是一个使用sched_setaffinity和sched_getaffinity的包。

缺点是它是高度特定于Linux的。

如果您在linux上,请在启动程序时使用taskset

通过fork(2)创建的子级继承其父级的CPU关联掩码。关联掩码保存在整个execve(2)中。

TASKSET(1)
Linux User’s Manual
TASKSET(1)

NAME taskset - retrieve or set a process’s CPU affinity

SYNOPSIS taskset [options] mask command [arg]... taskset [options] -p [mask] pid

DESCRIPTION taskset is used to set or retrieve the CPU affinity of a running process given its PID or to launch a new COMMAND with a given CPU affinity. CPU affinity is a scheduler property that "bonds" a process to a given set of CPUs on the system. The Linux scheduler will honor the given CPU affinity and the process will not run on any other CPUs. Note that the Linux scheduler also supports natural CPU affinity: the scheduler attempts to keep processes on the same CPU as long as practical for performance reasons. Therefore, forcing a specific CPU affinity is useful only in certain applications.

The CPU affinity is represented as a bitmask, with the lowest order bit corresponding to the first logical CPU and the highest order bit corresponding to the last logical CPU. Not all CPUs may exist on a given sys‐ tem but a mask may specify more CPUs than are present. A retrieved mask will reflect only the bits that cor‐ respond to CPUs physically on the system. If an invalid mask is given (i.e., one that corresponds to no valid CPUs on the current system) an error is returned. The masks are typically given in hexadecimal.

在我的双核机器上,进程总数是可以接受的,也就是说,如果我这样做了

p = Pool(1)

那么在任何给定的时间里我只能看到一个CPU在使用。进程可以自由迁移到不同的处理器,但随后另一个处理器空闲。我不知道你所有的处理器是如何同时使用的,所以我不明白这与你的I/O问题有什么关系。当然,如果您的模拟是I/O绑定的,那么无论核心使用情况如何,您都会看到缓慢的I/O。。。

相关问题 更多 >