2012-01-09 2 views
4

안녕하세요. 감사합니다. PLINQ를 사용할 때 메모리 예외를 피하려면 어떻게합니까?

배경 나는 많은 시간, 또는 병렬 컴퓨팅 하나를 필요로하는 컴퓨팅 작업을해야합니다.

구체적으로 약 50 개의 이미지 목록을 반복하여 Base64로 인코딩 한 다음 새로 인코딩 된 각 항목과 약 2000 Base64 문자열 인코딩 이미지가 포함 된 XML 파일의 값 사이의 Levenshtein 거리를 계산해야합니다. 가장 작은 Lev를 가진 XML 파일에서 문자열을 찾습니다. 벤치 마크 문자열과의 거리입니다.

Parallel.ForEach(candidates, item => findImage(total,currentWinner,benchmark,item)); 

을 작업은 빠른 속도로를 따라 경주, 화려하게 시작합니다

정기 foreach 루프 작동하지만 그래서 난 내 코어 i7 멀티 코어 프로세서를 활용하는 PLINQ를 사용하기로 선택한 너무 느립니다 , 그런 다음 "Out of Memory"예외가 발생합니다.

저는 C#, .NET 4, Forms App을 사용하고 있습니다. 내가 사용 가능한 메모리가 부족하지 않도록

질문

은 어떻게 PLINQ 코드를 조정할 수 있습니까?

private void btnGo_Click(object sender, EventArgs e) 
{ 
    XDocument doc = XDocument.Load(@"C:\Foo.xml"); 
    var imagesNode = doc.Element("images").Elements("image"); //Each "image" node contains a Base64 encoded string. 
    string benchmark = tbData.Text; //A Base64 encoded string. 
    IEnumerable<XElement> candidates = imagesNode; 

    currentWinner = 1000000; //Set the "Current" low score to a million and bubble lower scores into it's place iteratively. 

    Parallel.ForEach(candidates, i => { 
     dist = Levenshtein(benchmark, i.Element("score").Value); 
     if (dist < currentWinner) 
     { 
      currentWinner = dist; 
      path = i.Element("path").Value; 
     } 
    }); 
} 

:/샘플 코드 여기

업데이트는 PLINQ foreach을 iniate하기 위해 호출되는 방법이다. . .and 여기 Levenshtein 거리 방법은 다음과 같습니다 사전에

public static int Levenshtein(string s, string t) { 
      int n = s.Length; 
      int m = t.Length; 
      var d = new int[n + 1, m + 1]; 

      // Step 1 
      if (n == 0) 
      { 
       return m; 
      } 

      if (m == 0) 
      { 
       return n; 
      } 

      // Step 2 
      for (int i = 0; i <= n; d[i, 0] = i++) 
      { 
      } 

      for (int j = 0; j <= m; d[0, j] = j++) 
      { 
      } 

      // Step 3 
      for (int i = 1; i <= n; i++) 
      { 
       //Step 4 
       for (int j = 1; j <= m; j++) 
       { 
       // Step 5 
       int cost = (t[j - 1] == s[i - 1]) ? 0 : 1; 

       // Step 6 
       d[i, j] = Math.Min(
        Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1), 
        d[i - 1, j - 1] + cost); 
       } 
      } 
      // Step 7 
      return d[n, m]; 
      } 

감사합니다!

+0

코드를 입력하지 않았습니다. 우리가 현재 무엇을하는지 모른다면 어떻게 조정할지 조언 할 수 있습니까? – LukeH

+0

죄송합니다. 설명이 적절하다고 생각했습니다. 나는 그 소식을 업데이트 할 것이다. 감사. –

+0

@ LukeH- 코드가 추가되었습니다. 감사! –

답변

6

업데이트

다른 상황에서이 오류가 다시 발생합니다. 나는 높은 메모리 요구를 가진 데스크톱 애플 리케이션에서 일하고 있었다. 사용 가능한 모든 메모리에 액세스 할 수 있도록 64 비트 아키텍처 용 프로젝트를 설정했는지 확인하십시오. 내 프로젝트는 기본적으로 x86으로 설정되었으므로 메모리 예외가 계속 발생했습니다. 물론 이것은 배포 환경에서 64 비트 프로세서를 사용할 수있는 경우에만 작동합니다.

최종 업데이트

이에 조금 어려움을 겪고 후에는 운영자의 실수로 나타납니다

진행 라벨을 업데이트하기 위해 내가 병렬 스레드에서 UI 스레드에 대한 호출을했지만, 나는하지 않았다 스레드로부터 안전한 방식으로 수행합니다.

또한 디버거없이 앱을 실행했기 때문에 코드가 오버플로를 일으킨 병렬 스레드에서 UI 스레드를 업데이트하려고 할 때마다 캐치되지 않는 예외가 발생했습니다.

PLINQ에 대한 전문 지식이 없으면이 코드와 같이 바보 같은 코드 오류를 만들지 않는 한 모든 저급 할당 작업을 처리합니다.

다른 사람에게 도움이되기를 바랍니다.

관련 문제