2014-12-29 1 views
6


나는 Biopython를 사용 파이썬을하는 알고리즘을 구현하고있다. FASTA 파일에 여러 정렬 (동일한 길이의 시퀀스 집합)이 저장되어 있습니다. 각 정렬은 500 ~ 30000 seqs를 포함하며 각 시퀀스는 약 17000 요소 길이입니다. 각 시퀀스는 Bio.SeqRecord.SeqRecord 개체로 저장됩니다 (자세한 내용은 SeqRecord object's API documentation을 확인하십시오). 시퀀스뿐만 아니라 그에 대한 정보도 들어 있습니다. enter image description here파이썬 알고리즘을 병렬화하려고 노력하는 멀티 스레딩을 사용하여 피 GIL 제한


내가 원하기 때문에 :

seqs = AlignIO.read(seqs_filename, 'fasta') 
len_seqs = seqs.get_alignment_length() 
stats = {'-': [0.0] * len_seqs, 'A': [0.0] * len_seqs, 
     'G': [0.0] * len_seqs, 'C': [0.0] * len_seqs, 
     'T': [0.0] * len_seqs} 


내가 선명도 목적으로이 스케치를 포함 : 나는 MultipleSeqAlignment 객체를 반환합니다 (자세한 내용은 AlignIO module's API documentation 확인) Bio.AlignIO.read()를 사용하여 디스크에서 읽어 정렬의 분석을 paralelize, threading module (내가이 결정을 나중에 한 이유에 대한 자세한 내용)을 사용하여 각 사용 가능한 CPU의 조각을 작성합니다.

num_cpus = cpu_count() 
num_columns = ceil(len_seqs/float(num_cpus)) 
start_column = 0 
threads = [] 
for cpu in range(0, num_cpus): 
    section = (start_column, start_column + num_columns) 
    threads.append(CI_Thread(seqs_type, seqs, section, stats)) 
    threads[cpu].start() 

    start_column += num_columns 

stats 변수는 분석에 대한 정보를 저장하는 공유 변수입니다 (첫 번째 코드에서 볼 수있는 것처럼). 각 CPU가이 공유 변수의 다른 위치를 수정하려고하기 때문에 액세스 제어 또는 동기화 기본 요소가 필요하지 않다고 생각합니다. 에 대해 MultipleSeqAlignment 개체 전체를 복사하지 않으려 고하기 때문에 프로세스 대신 스레드를 사용하고 있습니다. 나는 약간의 조사를했고 발견했다 some stackoverflow posts 이것에 대해.

I했습니다 또한 내 알고리즘의 경우 100 % 확실 난 아직도 해요 "무서워"파이썬 글로벌 통역 잠금 (GIL)하지만 (I 모두 stackoverflowprogrammers 스택 교환에서에서 좋은 정보를 찾을 수 없음)에 대한 정보를 읽어 그것의 영향을받습니다. 내가 아는 한, 한 번에 하나씩 시퀀스를 메모리에로드하므로 모든 반복마다 IO를 수행합니다. 이것이 제가 전에 언급 한 this stackoverflow post에 언급 된 스레드를 사용하는 것이 좋은 생각이라고 생각합니다. 내가하지 확인하기 위해 인수 -f "%의 전자 %의 M"를 사용하여 timeit modulethe time command를 사용하여 일부 성능 테스트를 수행 한

for seq in seqs: 
    num_column = start_column 
    for column in seq.seq[start_column:end_column].upper(): 
     # [...] 
      try: 
       stats[elem][num_column] = get_some_info(column) 
      except TypeError: 
       raise TypeError(('"stats" argument should be a ' 
           'dict of lists of int')) 

: (각 스레드가 실행) 분석의 기본 구조는 다음과 같이 보입니다 경과 된 실제 시간 (초)뿐만 아니라 수명 동안 프로세스의 최대 상주 세트 크기 (Kbytes). 스레드를 사용하여 실행 시간을 순차 구현의 실행 시간을 스레드 수로 나눈 것 같습니다. 레지던트 세트의 최대 크기에 대해서는 여전히 패턴을 찾을 수 없습니다.


성능이나 선명도에 대한 다른 제안 사항이 있으시면 알려 주시기 바랍니다.


미리 감사드립니다.

+1

당신의 명성을 고려했을 때 내가 할 수있는 최선의 일은 질문을 업보 드하는 것이 었습니다. 이제는 10 가지 이상의 명성을 얻었습니다.하지만 미안합니다. 질문을하면 도움이됩니다. – ZdaR

+0

Thanks @Anmol_uppal! 방금 질문을 편집했습니다 :-) –

답변

2

일부 데이터에 대해 CPU 집약적 인 알고리즘을 실행하려는 경우 스레딩은 도움이되지 않습니다.multiprocessing 모듈을 살펴 보겠습니다.이 모듈은 100MB 스캔 이미지에서 특수 OCR을 수행 한 프로젝트에서 큰 성공을 거두었습니다.

은 공유 메모리 문제를 해결하기 위해 이것을 고려하십시오 :
from multiprocessing import Pool 

def f(x): 
    return x*x 

if __name__ == '__main__': 
    pool = Pool(processes=4)    # start 4 worker processes 
    result = pool.apply_async(f, [10]) # evaluate "f(10)" asynchronously 
    print result.get(timeout=1)   # prints "100" unless your computer is *very* slow 
    print pool.map(f, range(10))   # prints "[0, 1, 4,..., 81]" 

pool.imap()pool.apply_async()를 살펴 보자.

희망을 얻었습니다.

+0

스레딩의 주요 용도 중 하나는 한 프로그램에서 한 번에 둘 이상의 코어로 처리 할 수 ​​있기 때문에 스레딩이 도움이되지 않는 이유를 설명하십시오. –

+0

하지만 파이썬 스레딩에서는 CPU 전력을 분할 할 때 실제로는 병렬 적이 지 않습니다. I/O, 네트워킹 및 이와 유사한 것들에 유용합니다. 어떤 이유로 다중 처리와 서브 프로세스 같은 라이브러리가 존재합니다. – whiterock

+0

어쨌든 CPython에서 그렇습니다. 그리고 그것은 질문자가 주변에서 벗어나려고하는 GIL 때문에 사실입니다. CPython에서 GIL을 사용하는 것이 불가능하다면 이유가 있다면 좋을 것입니다. BTW에서'다중 처리 '와'서브 프로세스'모듈은'os' 모듈에서 OS 의존적 함수의 집합으로 이전에 처리했던 것들을 합리화하는 것과 같은 다른 이유로 존재합니다. –

관련 문제