2017-11-04 1 views
0

기계 학습 알고리즘을 적응 적으로 조정하기 위해 내 프로그램의 특정 부분에서 스택 높이를 안정적으로 추적하려고합니다.스택 높이/재귀 깊이를 안정적으로 추적 할 수 있습니까?

는 지금, 내 코드는 다음과 같습니다 : 나는 ThreadStatic 필드 Interlocked를 사용하는 것은 필요하지 않다고 알고 있어요, 내가 Constrained Execution Regions 알고 있어요

private const int MaxStackHeight = 20; 

[ThreadStatic] 
private static int stackHeight; 

... 

try 
{ 
    var currentHeight = Interlocked.Increment(ref stackHeight); 
    var depthFactor = currentHeight/(double)MaxStackHeight; 
    // Use `depthFactor` to limit the amount of branching & recursion at this depth by choosing simpler candidates. 
} 
finally 
{ 
    Interlocked.Decrement(ref stackHeight); 
} 

. 그러나이 문제는 Monitor.Enter/Monitor.Exit 문제와 매우 유사하므로 CER을 사용하여 해결할 수 있다고 확신하지 못합니다. 예를 들어, Monitor의 솔루션은 .NET에서 추가 된 Monitor.TryEnter 오버로드 중 하나에서 사용할 수있는 out lockTaken 매개 변수를 사용하고 있습니다. Interlocked.Increment과 비슷한 전략이 있습니까? 모니터 (.NET 4+)에 대한

예 솔루션 : finally 블록은 제한된 실행 영역이기 때문에, 및 .NET 프레임 워크는 out lockTaken 매개 변수가 정확하게 설정되도록 보장하기 때문에

var lockTaken = false; 
try 
{ 
    Monitor.TryEnter(handle, ref lockTaken); 
} 
finally 
{ 
    if (lockTaken) 
    { 
     Monitor.Exit(handle); 
    } 
} 

이 작동합니다.

가능하지 않은 경우 두 가지 대안 중 하나를 선택할 수 있습니다.

  • 스택의 스택 높이를 전달합니다 (예 : 메소드 매개 변수로 전달). 이것은 코드베이스의 많은 메소드의 복잡성을 상당히 증가시킵니다.
  • 루트 호출 사이트에서 재귀 부분을 호출하기 전후에 stackHeight0으로 설정합니다 (예외가 발생한 경우에도 마찬가지 임). 이 느낌은 ... 나쁘다.

그래서, 내 사용 사례에 대해 가능한 유사한 무엇인가, 또는 나는 다른 방법에 의지해야합니까?

편집 :

추측 : 내가 필요로 할 때 내가 증가 재귀 호출하기 전에 값을 유지하고 복원 할

 var incremented = false; 
     try 
     { 
      RuntimeHelpers.PrepareConstrainedRegions(); 
      try 
      { 
      } 
      finally 
      { 
       stackHeight++; 
       incremented = true; 
      } 

      // Use `stackHeight` 
     } 
     finally 
     { 
      if (incremented) 
      { 
       stackHeight--; 
      } 
     } 

답변

2

, 예를 들면 :

var currentStackHeight = stackHeight; 
try { 
    for(var i = 0; i < 10; i++) { 
    stackHeight = currentStackHeight + 1; 
    recurseDeeper(); 
    } 
} 
finally { 
    stackHeight = currentStackHeight; 
} 
+0

그래, 그건 아주 간단합니다. 내가 왜 그렇게 생각하지 않았어? 클래식 overthinking ... –