2016-02-29 1 views
1

У меня проблема с близостью процессора и линейным целым программированием в 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? Любые предложения о том, как действовать?

+0

@ali_m Я запускаю его из оболочки. Рабочие места в настоящее время запущены, и я только пытаюсь настроить его как его работу. Я нашел идентификаторы родительского процесса, используя 'ps -o ppid = 103841', а затем выполнил ту же команду' taskset', но результат такой же, как и раньше. Использование процессора фактически начинает расти, если вы смотрите 'top', но затем быстро опускается до ~ 50%. Таким образом, похоже, что настройка родительского слияния работает, но только на пару секунд. – nick

+0

@ali_m Я добавил фрагмент кода, который запускает дочерние процессы и ждет их завершения. Я также включил вывод 'pstree -s 103841' в вопрос. Здесь, а также 'init───screen───bash───python───python───2 * [{питона}]' – nick

+0

@ali_m не стоит беспокоиться о звучащих повторы. Я рад убедиться. Я разместил изображение выхода htop с изображением дерева.При нажатии «A» на PID '103785' он отображает все выбранные cpus. При нажатии «A» на PID '103841' выбирается только 1 процессор. Я попытался запустить 'taskset -p 0xffffffffffff 103785' и снова для' 103841'. Я проверил htop после запуска обоих, и близость к '103841' показала все выбранные, но после проверки через несколько секунд она сводилась к одному процессору. – nick

ответ

1

Я связался с поддержкой, и они предложили установить MSK_IPAR_NUM_THREADS на номер 1. Моя проблема решает долю секунды, поэтому она никогда не выглядела так, как будто она использовала несколько ядер. Должен был проверить документы для значений по умолчанию.

В моем коде я добавил task.putintparam(mosek.iparam.num_threads,1) сразу после заявления with. Это поставило проблему.

Смежные вопросы