2011-05-16 4 views
1

분산 형 시스템의 시뮬레이션을 만들고 싶습니다. 분산 형 (가능하면 병렬 !!) 방식으로 정보 (소모품)를 조사해야합니다. 예를 들어 다음과 같은 클래스가 있습니다.이 문제의 시나리오를 멀티 스레딩하는 방법은 무엇입니까?

public class Group{ 
public int identifier; 
public int[] members; 
public String name; 
public String[] supplies; 
public int[] neighbors;} 

각 그룹에는 이름이 있으며 구성원, 이웃 및 소모품 목록으로 구성되는 여러 그룹이 있으며 각 구성원에는 관련 정보 및 소모품이 들어있는 다른 그룹에 대한 정보와 목록이 있습니다.

1- 소모품에 대한 조사를하고 싶습니다. 첫째, 한 그룹 내에서 필요한 공급품을 찾지 못하면이 그룹의 이웃 인 모든 그룹 내에서 검색을해야합니다. 이 멀티 스레딩을 사용하여, 내 말은, 검색이 실패한 경우 여러 스레드를 사용하여 동시에 다른 모든 이웃 내부에서 검색을 수행해야합니다. 각각 하나의 이웃을 고려해야합니다. 10 개의 이웃이 있으면 10 개의 스레드가 있어야합니다. 만들었습니다 ...

2 이제 여러 그룹과 함께 처음으로 재검색을 시작하려는 경우 3 ~ 4 그룹 이상으로 시작하여 각기 다른 공급을 찾고, 또는 같은 .... + 검색을 호출하는 하나의 그룹은 다른 그룹의 이웃이 될 수 있습니다 ...

그럼 내 질문은 스레드를 사용하여이 시나리오를 달성하는 방법입니다.

PS.I 하나 개의 코어를 하나의 프로세서가있는 시스템을 가지고, 내가 실행 (오버 헤드)의 시간에 대한 상관 없어, 내가 원하는 건 ...이 문제를 시뮬레이션

감사에 대한 것입니다 모든 응답, 그리고 최고의 안부.

답변

1

CPU에 바인딩 된 문제가 있으므로 사용하려는 최적의 스레드 수는 보유한 코어 수입니다. 나는 각 스레드가 약 100 마이크로 초의 작업을하도록하거나 유용한 작업보다 더 많은 머리를 가질 수 있습니다. 예 : 10K 노드를 검색하면 약 100 명이 작동한다는 것을 알 수 있습니다. 조심하지 않으면 멀티 스레드 응용 프로그램이 단일 스레드 응용 프로그램보다 몇 배 느려질 수 있습니다.

그래서 작업을 나눠서 각 스레드마다 약 1K에서 100K 개의 노드가 있으므로 동시 코어의 코어 수를 제한 할 수 있습니다.

+0

감사합니다.하지만 실행 시간 (오버 헤드)에 신경 쓰지 않고 원하는 것은이 문제를 시뮬레이트하는 것입니다. – jojo

+0

Executor를 사용하여 ExecutorService를 만들고 필요한 작업을 수행하기 위해 작업을 제출합니다 . 최상의 성능을 위해 newSingleThreadExecutor()를 사용합니다. –

1

두 번째 요구 사항을 이해할 수 없지만 첫 번째 요구 사항은 여기에 가능한 방법입니다. 그 전에는 기술적으로 프로세스가 완전히 CPU 바운드가 아니며 I/O 바운드 (네트워크)이기도합니다. 그래서, muti-threaded로 만들면 필요한 속도 향상을 제공 할 것이라고 가정하지 마십시오. 귀하의 개발 환경이 단일 프로세서 및 단일 코어라고 가정하고 있지만 귀하의 전개 환경은 그렇지 않을 수도 있습니다.

위로 제안. 정보 스카우트가 가능한 스레드 풀이있는 GroupPool 클래스를 만듭니다. 스레드 수는 런타임 구성 매개 변수를 통해 구성 할 수 있습니다. 구성 파일에서이 매개 변수를 읽고 실행 가능한 개체 풀을 만드는 팩토리 클래스를 만들 수 있습니다.

이러한 개체 각각은 인접 노드에 대한 하나의 연결을 나타냅니다. [TODO] 공급자 노드에서 정보를 찾지 못했다면 공급자 노드 나 공급 업체의 공급 업체 등을 검색하고 싶습니까? 주기 탐지 문제가있다.일단 이러한 스레드 객체가 정보를 찾아서 찾으면 팩토리 객체의 세마포어를 업데이트합니다 (이 객체를 더 나은 디자인이 될 별도의 객체로 옮길 수 있습니다). 또한 공급자 ID를 보냅니다 (별도의 객체가 의미가 있음)

이 수정 된 세마포어에 대한 수신기를 가질 수 있으며 값이 변경 되 자마자 정보를 찾고 해당 객체에서 공급 업체 ID를 얻게됩니다. 정보를 얻은 후에는 스레드 풀에 알림을 보내서 이미 정보를 찾은 것처럼 실행 가능한 개체를 종료 할 수 있습니다.

바이너리 답장 (데이터 및 공급 업체 찾기는 괜찮음)을 찾고 있는지 여부와 재발생을 원할 경우 위의 복잡성이 증가합니다.

문제의 구조를 설계하는 데 도움이되기를 바랍니다.

1

단일 CPU 컴퓨터에서 멀티 스레딩하는 데 성능상의 이점이 없습니다. 이는 한 번에 하나의 스레드 만 실행할 수 있고 스레드간에 전환 시간이 있기 때문에 실제로 원하는 자원이있는 그룹을 찾는 데 더 많은 시간이 걸릴 것이기 때문입니다.

개인적으로는 처음 그룹의 이웃을 반복하고 리소스를 확인합니다. 그런 다음 리소스가 발견되지 않으면 각 하위 그룹에서 검색을 호출하여 이미 확인 된 그룹 목록을 전달하므로 이미 확인 된 그룹은 건너 뛸 수 있습니다.

public Group searchForGroupWithResource(Resource resource){ 
    List<Group> groupsToCheck = new ArrayList<Group>(); 
    groupsToCheck.add(this); 
    int currentIndex = 0; 
    while(currentIndex < groupsToCheck.size()){ 
     Group currentGroup = groupsToCheck.get(currentIndex); 
     if(currentGroup.hasResource(resource)){ 
      return currentGroup; 
     } 
     groupsToCheck.addAll(currentGroup.getNeighbors(groupsToCheck)); 
     currentIndex++; 
    } 
    return null; 
} 

public List<Group> getNeighbors(List<Group> excludeGroups){ 
    //Get non-excluded neighbors 
    List<Group> returnNeighbors = new ArrayList<Group>(); 
    for(Group neighbor : neighbors){ 
     boolean includeGroup = true; 
     for(Group excludeGroup : excludeGroups){ 
      if(excludeGroup.equals(neighbor)){ 
       includeGroup = false; 
       break; 
      } 
     } 
     if(includeGroup){ 
      returnNeighbors.add(neighbor); 
     } 
    } 
    return returnNeighbors; 
} 

참고 : 같은 뭔가가 여전히 멀티 스레딩을 위해 이동하는 것을 결정하는 경우에, 나는이 모든 스레드에 액세스 할 수있는 검색에 대한 정보를 저장하는 일반적인 객체를 건의 할 것입니다. 이렇게하면 확인 된 그룹 (동일한 그룹을 두 번 확인하지 않음)과 필요한 소모품을 찾을 수 있는지 (자원 검사를 중지 할 수 있도록)를 지정합니다.

관련 문제