У меня проблема с близостью процессора и линейным целым программированием в MOSEK. Моя программа распараллеливается с использованием модуля multiprocessing
в Python
, поэтому MOSEK работает одновременно на каждом процессе. Машина имеет 48 ядер, поэтому я запускаю 48 одновременных процессов, используя класс Pool
. В их документации указано, что API is thread safe.Проблема с привязкой к CPU с использованием API Python для MOSEK
После запуска программы ниже выведено значение top
. Это показывает, что ~ 50% процессора простаивает. Показаны только первые 20 строк верхнего вывода.
top - 22:04:42 up 5 days, 14:38, 3 users, load average: 10.67, 13.65, 6.29
Tasks: 613 total, 47 running, 566 sleeping, 0 stopped, 0 zombie
%Cpu(s): 46.3 us, 3.8 sy, 0.0 ni, 49.2 id, 0.7 wa, 0.0 hi, 0.0 si, 0.0 st
GiB Mem: 503.863 total, 101.613 used, 402.250 free, 0.482 buffers
GiB Swap: 61.035 total, 0.000 used, 61.035 free. 96.250 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
115517 njmeyer 20 0 171752 27912 11632 R 98.7 0.0 0:02.52 python
115522 njmeyer 20 0 171088 27472 11632 R 98.7 0.0 0:02.79 python
115547 njmeyer 20 0 171140 27460 11568 R 98.7 0.0 0:01.82 python
115550 njmeyer 20 0 171784 27880 11568 R 98.7 0.0 0:01.64 python
115540 njmeyer 20 0 171136 27456 11568 R 92.5 0.0 0:01.91 python
115551 njmeyer 20 0 371636 31100 11632 R 92.5 0.0 0:02.93 python
115539 njmeyer 20 0 171132 27452 11568 R 80.2 0.0 0:01.97 python
115515 njmeyer 20 0 171748 27908 11632 R 74.0 0.0 0:03.02 python
115538 njmeyer 20 0 171128 27512 11632 R 74.0 0.0 0:02.51 python
115558 njmeyer 20 0 171144 27528 11632 R 74.0 0.0 0:02.28 python
115554 njmeyer 20 0 527980 28728 11632 R 67.8 0.0 0:02.15 python
115524 njmeyer 20 0 527956 28676 11632 R 61.7 0.0 0:02.34 python
115526 njmeyer 20 0 527956 28704 11632 R 61.7 0.0 0:02.80 python
Я проверил MOSEK parameters раздел документации, и я не видел, что связано с аффинностью CPU. У них есть несколько флагов, связанных с многопотоком в оптимизаторе. Эти флаги устанавливаются как off
по умолчанию, и при избыточном настройке на off
никаких изменений.
Я проверил близость процессора рабочих заданий на python, и многие из них связаны с одним и тем же процессором. Но, странная часть, я не могу установить близость процессора, или, по крайней мере, кажется, что он изменился снова вскоре после того, как я его изменил.
Я выбрал одну из заданий и установил близость процессора, запустив taskset -p 0xFFFFFFFFFFFF 115526
. Я делаю это 10 раз с 1 секундой между ними. Вот маска сродства cpu после каждого вызова taskset
.
pid 115526's current affinity mask: 10
pid 115526's new affinity mask: ffffffffffff
pid 115526's current affinity list: 7
pid 115526's current affinity mask: 800000000000
pid 115526's new affinity mask: ffffffffffff
pid 115526's current affinity list: 0-47
pid 115526's current affinity mask: 800000000000
pid 115526's new affinity mask: ffffffffffff
pid 115526's current affinity list: 0-47
pid 115526's current affinity mask: ffffffffffff
pid 115526's new affinity mask: ffffffffffff
pid 115526's current affinity list: 0-47
pid 115526's current affinity mask: ffffffffffff
pid 115526's new affinity mask: ffffffffffff
pid 115526's current affinity list: 0-47
pid 115526's current affinity mask: ffffffffffff
pid 115526's new affinity mask: ffffffffffff
pid 115526's current affinity list: 0-47
pid 115526's current affinity mask: 200000000000
pid 115526's new affinity mask: ffffffffffff
pid 115526's current affinity list: 47
pid 115526's current affinity mask: ffffffffffff
pid 115526's new affinity mask: ffffffffffff
pid 115526's current affinity list: 0-47
pid 115526's current affinity mask: 800000000000
pid 115526's new affinity mask: ffffffffffff
pid 115526's current affinity list: 0-47
pid 115526's current affinity mask: 800000000000
pid 115526's new affinity mask: ffffffffffff
pid 115526's current affinity list: 0-47
Похоже, что что-то постоянно меняет сродство к процессору во время выполнения.
Я также попытался установить род функции cpu родительского процесса, но он имеет тот же эффект.
Вот код, я бегу.
import mosek
import sys
import cPickle as pickle
import multiprocessing
import time
def mosekOptim(aCols,aVals,b,c,nCon,nVar,numTrt):
"""Solve the linear integer program.
Solve the program
max c' x
s.t. Ax <= b
"""
## setup mosek
with mosek.Env() as env, env.Task() as task:
task.appendcons(nCon)
task.appendvars(nVar)
inf = float("inf")
## c
for j,cj in enumerate(c):
task.putcj(j,cj)
## bounds on A
bkc = [mosek.boundkey.fx] + [mosek.boundkey.up
for i in range(nCon-1)]
blc = [float(numTrt)] + [-inf for i in range(nCon-1)]
buc = b
## bounds on x
bkx = [mosek.boundkey.ra for i in range(nVar)]
blx = [0.0]*nVar
bux = [1.0]*nVar
for j,a in enumerate(zip(aCols,aVals)):
task.putarow(j,a[0],a[1])
for j,bc in enumerate(zip(bkc,blc,buc)):
task.putconbound(j,bc[0],bc[1],bc[2])
for j,bx in enumerate(zip(bkx,blx,bux)):
task.putvarbound(j,bx[0],bx[1],bx[2])
task.putobjsense(mosek.objsense.maximize)
## integer type
task.putvartypelist(range(nVar),
[mosek.variabletype.type_int
for i in range(nVar)])
task.optimize()
task.solutionsummary(mosek.streamtype.msg)
prosta = task.getprosta(mosek.soltype.itg)
solsta = task.getsolsta(mosek.soltype.itg)
xx = mosek.array.zeros(nVar,float)
task.getxx(mosek.soltype.itg,xx)
if solsta not in [ mosek.solsta.integer_optimal,
mosek.solsta.near_integer_optimal ]:
print "".join(mosekMsg)
raise ValueError("Non optimal or infeasible.")
else:
return xx
def reps(secs,*args):
start = time.time()
while time.time() - start < secs:
for i in range(100):
mosekOptim(*args)
def main():
with open("data.txt","r") as f:
data = pickle.loads(f.read())
args = (60,) + data
pool = multiprocessing.Pool()
jobs = []
for i in range(multiprocessing.cpu_count()):
jobs.append(pool.apply_async(reps,args=args))
pool.close()
pool.join()
if __name__ == "__main__":
main()
Код нечетких данных, которые я предварительно вычислил. Эти объекты являются ограничениями и коэффициентами для линейной программы. У меня есть код и этот файл данных, размещенный в этом repository.
Кто-нибудь еще это поведение с MOSEK? Любые предложения о том, как действовать?
@ali_m Я запускаю его из оболочки. Рабочие места в настоящее время запущены, и я только пытаюсь настроить его как его работу. Я нашел идентификаторы родительского процесса, используя 'ps -o ppid = 103841', а затем выполнил ту же команду' taskset', но результат такой же, как и раньше. Использование процессора фактически начинает расти, если вы смотрите 'top', но затем быстро опускается до ~ 50%. Таким образом, похоже, что настройка родительского слияния работает, но только на пару секунд. – nick
@ali_m Я добавил фрагмент кода, который запускает дочерние процессы и ждет их завершения. Я также включил вывод 'pstree -s 103841' в вопрос. Здесь, а также 'init───screen───bash───python───python───2 * [{питона}]' – nick
@ali_m не стоит беспокоиться о звучащих повторы. Я рад убедиться. Я разместил изображение выхода htop с изображением дерева.При нажатии «A» на PID '103785' он отображает все выбранные cpus. При нажатии «A» на PID '103841' выбирается только 1 процессор. Я попытался запустить 'taskset -p 0xffffffffffff 103785' и снова для' 103841'. Я проверил htop после запуска обоих, и близость к '103841' показала все выбранные, но после проверки через несколько секунд она сводилась к одному процессору. – nick