2011-10-06 2 views
1

C# 코드를 작성하는 명령어 수준 병렬 처리에 영향을 줄 수있는 방법이 있습니까? 즉, ILP를 가장 잘 사용하는 컴파일러 코드를 "도울"수있는 방법이 있습니까? 컴퓨터 아키텍처의 몇 가지 개념을 추상화하려고 시도하고 있기 때문에 이것을 묻습니다. 이것이 가능한지 알아야합니다. 그렇지 않다면, 나는 ILP에서 추상적으로 멀리 떨어지게 될 것입니다.관리 코드가 명령어 수준의 병렬 처리에 영향을 미칠 수 있습니까?

EDIT : 어떤 식 으로든 C#을 사용하여 ILP를 악용하고 싶지는 않습니다. 제 질문은 정확히 반대입니다. 인용구 : "C#에서 ILP를 개발할 방법이 없기를 바랍니다"

감사합니다.

+0

이것은 .Net의 추상화에 대한 잘못된 수준입니다. –

+0

@DaveHillier : 흠? 그것이 바로 제가 알아 내려고 노력하는 것입니다. –

+0

아마도 사용하는 특정 기술을 언급하고 그들이 여전히 적용되는지 질문해야합니다. 왜 ILP에 관심이 있습니까? –

답변

0

명령어 수준의 병렬 처리를 수행 할 때 JIT가 유용합니다. JIT가 실제로 어떤 최적화 작업을 수행하는지 알고 있습니까? 정말 필요한 경우 C++과 같은 다른 언어를 선택합니다.

ILP를 최대한 활용하려면 종속성 체인을 해제해야합니다. 이것은 여전히 ​​적용됩니다. 이 thread을 참조하십시오.

그러나 모든 추상화를 통해이 문제를 효과적으로 활용하는 것이 가능하지만 가장 극단적 인 경우는 의심 스럽습니다. 당신이 필요한 곳에 어떤 예가 있습니까?

+0

감사합니다. 당신은 거의 질문에 답했습니다. 질문을 다시 읽으면 어떤 방식 으로든 C#을 사용하여 ILP를 악용하려는 것이 아니라 ** 알 수 있습니다. 제 질문은 정확히 반대입니다. 말하자면 : "C#에서 ILP를 개발할 방법이 없길 바랍니다." –

+0

왜 신경 쓰시나요? 그것은 중요하지 않습니다. 여러분은 이미 아키텍처로부터 추상화되어 있습니다. C#은 IL로 컴파일되어 JIT가 기계 명령어로 바뀝니다. 귀하의 CPU가 원하는대로 할 것입니다;) –

0

IL 또는 C# .NET 컴파일러에 영향을 미치거나 힌트를주기위한 명시 적 또는 직접적인 방법이 없습니다. 이것은 전적으로 컴파일러 작업입니다.

당신이 할 수있는 유일한 영향은 프로그램을 구조화하여 (보장은 아닐지라도) 당신을 위해 이것을 할 수 있으며 구조체에 영향을 미쳤는지를 아는 것이 어려울 것입니다 아닙니다. 이것은 .NET 언어와 IL에서 잘 추상화되어 있습니다.

1

ILP는 CPU의 기능입니다. 당신은 그것을 통제 할 수있는 방법이 없습니다. 컴파일러는 종속성 체인을 제거하여 악용하기 위해 최선을 다합니다.

.Net JIT 컴파일러가 포함될 수 있지만 이에 대한 증거는 없습니다.

0

CLI에서 ILP를 사용할 수 있습니다.

내가 전에 간단한 이미지 처리 작업의 코드를 작성하고, "비트"빨리 내 코드를 만들어에 optimazation 이런 종류의 사용 : 그래서 짧은 대답은 제

약간 더 길다.

A "짧은"예 :

static void Main(string[] args) 
{ 
    const int ITERATION_NUMBER = 100; 

    TimeSpan[] normal = new TimeSpan[ITERATION_NUMBER]; 
    TimeSpan[] ilp = new TimeSpan[ITERATION_NUMBER]; 

    int SIZE = 4000000; 
    float[] data = new float[SIZE]; 
    float safe = 0.0f; 

    //Normal for 
    Stopwatch sw = new Stopwatch(); 

    for (int iteration = 0; iteration < ITERATION_NUMBER; iteration++) 
    { 
    //Initialization 
    for (int i = 0; i < data.Length; i++) 
    { 
     data[i] = 1.0f; 
    } 

    sw.Start(); 
    for (int index = 0; index < data.Length; index++) 
    { 
     data[index] /= 3.0f * data[index] > 2.0f/data[index] ? 2.0f/data[index] : 3.0f * data[index]; 
    } 
    sw.Stop(); 
    normal[iteration] = sw.Elapsed; 

    safe = data[0]; 

    //Initialization 
    for (int i = 0; i < data.Length; i++) 
    { 
     data[i] = 1.0f; 
    } 

    sw.Reset(); 

    //ILP For 
    sw.Start(); 
    float ac1, ac2, ac3, ac4; 
    int length = data.Length/4; 
    for (int i = 0; i < length; i++) 
    { 
     int index0 = i << 2; 

     int index1 = index0; 
     int index2 = index0 + 1; 
     int index3 = index0 + 2; 
     int index4 = index0 + 3; 

     ac1 = 3.0f * data[index1] > 2.0f/data[index1] ? 2.0f/data[index1] : 3.0f * data[index1]; 

     ac2 = 3.0f * data[index2] > 2.0f/data[index2] ? 2.0f/data[index2] : 3.0f * data[index2]; 

     ac3 = 3.0f * data[index3] > 2.0f/data[index3] ? 2.0f/data[index3] : 3.0f * data[index3]; 

     ac4 = 3.0f * data[index4] > 2.0f/data[index4] ? 2.0f/data[index4] : 3.0f * data[index4]; 

     data[index1] /= ac1; 
     data[index2] /= ac2; 
     data[index3] /= ac3; 
     data[index4] /= ac4; 
    } 
    sw.Stop(); 
    ilp[iteration] = sw.Elapsed; 

    sw.Reset(); 
    } 
    Console.WriteLine(data.All(item => item == data[0])); 
    Console.WriteLine(data[0] == safe); 
    Console.WriteLine(); 

    double normalElapsed = normal.Max(time => time.TotalMilliseconds); 
    Console.WriteLine(String.Format("Normal Max.: {0}", normalElapsed)); 
    double ilpElapsed = ilp.Max(time => time.TotalMilliseconds); 
    Console.WriteLine(String.Format("ILP Max.: {0}", ilpElapsed)); 
    Console.WriteLine(); 
    normalElapsed = normal.Average(time => time.TotalMilliseconds); 
    Console.WriteLine(String.Format("Normal Avg.: {0}", normalElapsed)); 
    ilpElapsed = ilp.Average(time => time.TotalMilliseconds); 
    Console.WriteLine(String.Format("ILP Avg.: {0}", ilpElapsed)); 
    Console.WriteLine(); 
    normalElapsed = normal.Min(time => time.TotalMilliseconds); 
    Console.WriteLine(String.Format("Normal Min.: {0}", normalElapsed)); 
    ilpElapsed = ilp.Min(time => time.TotalMilliseconds); 
    Console.WriteLine(String.Format("ILP Min.: {0}", ilpElapsed)); 
} 

결과이다 (닷넷 프레임 워크 4.0 클라이언트 프로파일 릴리스에) : 가상 머신 (I 더 ILP와 생각)에

:

진정한 진정한

도 아니다 최대 : 111,1894
,ILP 최대 : 106,886

아니다 평균 : 78,163619
ILP 평균 : 77,682513

아니다 최소.: 58.3035
ILP 분 :.

진정한 진정한

도 아니다 최대 : :. 40.5892
ILP 최대 : 제논
에 56.7672

. 30.8906

아니다 평균 :. 35.637308
ILP 평균 :. 25.45341

아니다 최소 :. 34.4247
ILP 분 :. 결과의 23.7888

설명 :

디버그에서

, 컴파일러에 의해 applyed 더 optization이 없지만, 루프에 대한 두 번째는보다 더 최적 첫 번째는 너무 큰 차이가 있습니다.

대답은 릴리스 패션 사례 어셈블리의 실행의 결과로 보인다. 일리노이 컴파일러/JIT는 성능 counsumption을 (심지어 ILP 생각) 최소화하기 위해 최선의 남편. 하지만 당신은 루프에 대한 두 번째 같은 코드를 만들어 여부, 당신은 특별한 경우에 더 나은 결과를 도달 할 수 있고, 두 번째 루프는 일부 achitectures의 첫 번째 하나를 통해 수행 할 수 있습니다. 그러나

당신은 안타깝게도 JIT 언급 한 바와 같이

의 자비에 있습니다. 슬픈 것은 구현에 대한 언급은 (짧은 단락은 사양 friendlyness 될 수 있음) ILP처럼, 더 최적화를 정의하지 않습니다 수있다. 그러나 그들은 코드의 건축 optomizations의 모든 형태를 열거 할 수 없으며, CLI는 높은 수준에있는이 잘 떨어져 .NET 언어와 IL에서 추상화되어

.

이 단지 실험 방법을 답변하는 매우 복잡한 문제이다. 나는 우리가 훨씬 더 정확한 결과이 같은 방법을 얻을 수 있다고 생각하지 않습니다. 그리고 나는 질문이 C 번호에 따라되지 becuse, 그것은 CLI의 구현에 따라 missleading 생각합니다.

이 많은 영향을 미치는 요인, 그리고 우리는 블랙 박스로 생각까지 열심히 올바르게 JIT에 대한이 생각 같은 질문에 대답 할 수 있었다.

나는 페이지 512-513에 루프 벡터화 및 autothreading에 대한 것들을 발견. http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-335.pdf

나는 그들이 명시 적으로 JIT는이 같은 경우에 행동해야하는 방법을 지정하지 않은 생각하고 impelenters를 선택할 수 있습니다 최적화의 방법. 그래서 난 당신이 더 최적의 코드를 작성할 수 있으며, 그것은/구현 가능한 경우 JIT는 ILP를 사용하려고 할 경우, 영향을 미칠 수 있다고 생각합니다.

나는 그들은 지정하지 않기 때문에, 가능성이 있습니다 생각합니다.

그래서 대답은 아니 것 같다 사양이 말을하지 않으면 난 당신이 멀리 CLI의 경우에는 ILP에서 추상적 할 수 없습니다 보라.

업데이트는 :

나는 전에 블로그 게시물을 찾았지만, 지금까지 발견되지 않은 : http://igoro.com/archive/gallery-of-processor-cache-effects/ 예 네 가지 질문에 대한 짧은,하지만 적절한 대답이 포함되어 있습니다.

관련 문제