Реализация многоядерных потоков на этом алгоритме - PullRequest
0 голосов
/ 25 июля 2011

Я пытаюсь найти способ, чтобы следующий алгоритм обрабатывался на нескольких ядрах, но я не могу понять, в чем дело.Я думаю, что использование заблокированного итератора, совместно используемого несколькими процессами, было бы не самым эффективным способом.

 def sortCharset(set):
   _set = ""
   for c in set:
     if c not in _set:
       _set += c
   set = _set
   del _set
   set = list(set)
   set.sort()
   return "".join(set)
 
 
 def stringForInt(num, set, length):
   setLen = len(set)
   string = ""
   string += set[num % setLen]
   for n in xrange(1,length):
     num //= setLen
     string += set[num % setLen]
   return string
 
 
 def bruteforce(set, length, raw = False):
   if raw is False:
     set = sortCharset(set)
 
   for n in xrange(len(set) ** length):
     yield stringForInt(n, set, length)

Краткое объяснение: код используется для создания любой возможной комбинации из набора символов, то есть для взломапароль.(Конечно, я не намерен, просто немного Py-обучение.; -)

Каков хороший способ запустить этот алгоритм на нескольких ядрах?

1 Ответ

2 голосов
/ 25 июля 2011

Вопрос на самом деле не в стиле именования или в том, как извлечь отсортированный набор символов из строки.

Возможно, вы захотите заглянуть в модуль multiprocessing . Я в значительной степени многоядерный параллелизм n00b w / r / t, но что-то работает:

import multiprocessing, itertools

def stringForInt(args):
    num, charset, length = args ## hack hack hack
    setlen = len(charset)
    s = []
    s.append(charset[num % setlen])
    for n in xrange(1, length):
        num //= setlen
        s.append(charset[num % setlen])
    return ''.join(s)

def bruteforce(charset, length, mapper, raw=False):
    if not raw:
        charset = sorted(set(charset))
    return mapper(stringForInt, ((n,charset,length) for n in xrange(len(charset)**length)))

if __name__ == '__main__':
    import time, sys
    if len(sys.argv) == 1 or sys.argv[1] == 'map':
        mapper = map
    else:
        p = multiprocessing.Pool()
        pfunc = {'pmap':p.map,
                 'imap':p.imap,
                 'imapu':p.imap_unordered}[sys.argv[1]]
        mapper = lambda f, i: pfunc(f, i, chunksize=5)
    o = bruteforce('abcdefghijk',6,mapper)
    if not isinstance(o, list):
        list(o)

Характер взлома состоит в том, что вам нужно использовать объекты для выбора для функций в multiprocessing, и только функции, которые определены на верхнем уровне, могут быть активированы. (Существуют и другие способы обойти это, используя multiprocessing.Value или multiprocessing.Manager, но в действительности они не стоят того, чтобы их использовать в настоящих целях.)

Вот вывод для различных прогонов:

$ for x in map pmap imap imapu ; do time python mp.py $x; done

real    0m9.351s
user    0m9.253s
sys     0m0.096s

real    0m10.523s
user    0m20.753s
sys     0m0.176s

real    0m4.081s
user    0m13.797s
sys     0m0.276s

real    0m4.215s
user    0m14.013s
sys     0m0.236s
...