Nice programing

Reactive Framework, PLINQ, TPL 및 Parallel Extensions는 서로 어떤 관련이 있습니까?

nicepro 2020. 11. 17. 21:07
반응형

Reactive Framework, PLINQ, TPL 및 Parallel Extensions는 서로 어떤 관련이 있습니까?


적어도 .NET 4.0이 출시 된 이후로 Microsoft는 병렬 및 비동기 프로그래밍을 지원하기 위해 많은 노력을 기울인 것으로 보이며이를 둘러싼 많은 API와 라이브러리가 등장한 것 같습니다. 특히 다음과 같은 멋진 이름이 최근 모든 곳에서 끊임없이 언급됩니다.

  • 반응 프레임 워크,
  • PLINQ (Parallel LINQ),
  • TPL (Task Parallel Library) 및
  • 병렬 확장.

이제는 모두 Microsoft 제품인 것처럼 보이며 모두 .NET 용 비동기 또는 병렬 프로그래밍 시나리오를 대상으로하는 것 같습니다. 그러나 각각이 실제로 무엇이며 서로 어떻게 관련되어 있는지는 명확하지 않습니다. 일부는 실제로 같은 것일 수 있습니다.

간단히 말해, 누구든지 무엇이 무엇인지 바로 기록 할 수 있습니까?


PLINQ (Parallel Linq)는 병렬로 실행되도록 일반 Linq 쿼리를 작성하는 새로운 방법입니다. 즉, 프레임 워크는 여러 스레드에서 쿼리 실행을 자동으로 처리하여 더 빨리 완료되도록합니다 (예 : 여러 CPU 코어 사용). ).

예를 들어, 여러 문자열이 있고 문자 "A"로 시작하는 모든 문자열을 가져 오려고한다고 가정 해 보겠습니다. 다음과 같이 쿼리를 작성할 수 있습니다.

var words = new[] { "Apple", "Banana", "Coconut", "Anvil" };
var myWords = words.Select(s => s.StartsWith("A"));

그리고 이것은 잘 작동합니다. 하지만 검색 할 단어가 50,000 개라면 각 테스트가 독립적이라는 사실을 활용하고이를 여러 코어로 분할 할 수 있습니다.

var myWords = words.AsParallel().Select(s => s.StartsWith("A"));

이것이 일반 쿼리를 여러 코어에서 실행되는 병렬 쿼리로 전환하기 위해 수행해야하는 전부입니다. 꽤 깔끔한.


TPL은 (태스크 라이브러리를 병렬) 종류 PLINQ에 대한 보완의, 그리고 함께 그들은 병렬 확장을 구성합니다. PLINQ는 대체로 부작용 없는 기능적 프로그래밍 스타일에 기반을두고있는 반면 , 부작용은 정확히 TPL의 목적입니다. 병렬로 물건을 검색 / 선택하는 대신 실제로 병렬로 작업 하려면 TPL을 사용합니다.

TPL은 본질적이다 Parallel의 오버로드를 노출 클래스 For, ForeachInvoke. Invoke에서 작업을 대기열에 추가하는 것과 비슷 ThreadPool하지만 사용하기가 조금 더 간단합니다. IMO에서 더 흥미로운 부분은 ForForeach. 예를 들어 압축하려는 파일이 많이 있다고 가정 해 보겠습니다. 일반 순차 버전을 작성할 수 있습니다.

string[] fileNames = (...);
foreach (string fileName in fileNames)
{
    byte[] data = File.ReadAllBytes(fileName);
    byte[] compressedData = Compress(data);
    string outputFileName = Path.ChangeExtension(fileName, ".zip");
    File.WriteAllBytes(outputFileName, compressedData);
}

다시 말하지만,이 압축의 각 반복은 서로 완전히 독립적입니다. 한 번에 여러 작업을 수행하여 속도를 높일 수 있습니다.

Parallel.ForEach(fileNames, fileName =>
{
    byte[] data = File.ReadAllBytes(fileName);
    byte[] compressedData = Compress(data);
    string outputFileName = Path.ChangeExtension(fileName, ".zip");
    File.WriteAllBytes(outputFileName, compressedData);
});

다시 말하지만,이 작업을 병렬화하는 데 필요한 전부입니다. 이제 우리가 CompressFiles메서드 (또는 우리가 부르기로 결정한 것)를 실행하면 여러 CPU 코어를 사용하고 아마도 절반 또는 1/4의 시간에 완료 될 것입니다.

모든 것을 chucking하는 것보다 이것의 장점은 ThreadPool이것이 실제로 동시에 실행 된다는 것 입니다. 당신이 사용하는 경우 ThreadPool대신 (또는 그냥 일반 Thread인스턴스)이되지 않은 상태에서, 당신은 모든 작업이 완료되면 알아내는 방법을 마련 할 수 있고, 줄 몹시 복잡 많은 사람들이 경향이, 그것의 무언가를 망치거나 적어도 문제가 있습니다. Parallel수업 을 사용할 때 실제로 그것에 대해 생각할 필요가 없습니다. 멀티 스레딩 측면은 숨겨져 있으며 모두 뒤에서 처리됩니다.


Reactive Extensions (Rx)는 완전히 다른 짐승입니다. 이벤트 처리에 대해 생각하는 다른 방식입니다. 이것에 대해 다룰 자료가 정말 많지만 간단히 말해서 이벤트 핸들러를 이벤트에 연결하는 대신 Rx를 사용하면 이벤트 시퀀스를 처리 할 수 ​​있습니다 IEnumerable<T>. 시퀀스 ( ) 도 마찬가지 입니다. 특정 순서로 발생하는 일련의 이벤트를 감지하기 위해 항상 상태를 저장해야하는 무작위 시간에 비동기식으로 이벤트를 발생시키는 대신 반복적 인 방식으로 이벤트를 처리하게됩니다.

내가 찾은 Rx에서 가장 멋진 예 중 하나는 여기 입니다. "Linq to IObservable"섹션으로 건너 뛰어 그가 단 4 줄의 코드로 일반적으로 WPF에서 고통스러운 끌어서 놓기 처리기를 구현합니다. Rx는 이벤트의 구성제공합니다. 일반 이벤트 핸들러로는 실제로 가질 수없는 것입니다. 이와 같은 코드 스 니펫은 어디에서나 사용할 수있는 동작 클래스로 리팩토링하기가 쉽습니다.


그리고 그게 다야. .NET 4.0에서 사용할 수있는 멋진 기능 중 일부입니다. 물론 몇 가지가 더 있지만 이것들은 당신이 요청한 것입니다!


I like Aaronaught's answer, but I would say Rx and TPL solve different problems. Part of what the TPL team added are the threading primitives and significant enhancements to the building blocks of the runtime like the ThreadPool. And everything you list is built on top of these primitives and runtime features.

But the TPL and Rx solve two different problems. TPL works best when the program or algorithm is 'pulling & queuing'. Rx excels when the program or algorithm needs to 'react' to data from a stream (like mouse input or when receiving a stream of related messages from an endpoint like WCF).

You'd need the 'unit of work' concept from TPL to do work like the filesystem, iterating over a collection, or walking a hierarchy like a org chart. In each of those cases the programmer can reason about the overall amount of work, the work can be broken down into chunks of a certain size (Tasks), and in the case of doing computations over a hierarchy the tasks can be 'chained' together. So certain types of work lend themselves to the TPL 'Task Hierarchy' model, and benefit from the enhancements to plumbing like cancellation (see Channel 9 video on CancellationTokenSource). TPL also has lots of knobs for specialized domains like near real-time data processing.

Rx will be what most developers should end up using. It is how WPF applications can 'react' to external messages like external data (stream of IM messages to an IM client) or external input (like the mouse drag example linked from Aaronaught). Under the covers Rx uses threading primitives from TPL/BCL, threadsafe collections from TPL/BCL, and runtime objects like the ThreadPool. In my mind Rx is the 'highest-level' of programming to express your intentions.

Whether the average developer can get their head wrapped around the set of intentions you can express with Rx is yet to be seen. :)

But I think the next couple of years the TPL vs. Rx is going to be the next debate like LINQ-to-SQL vs. Entity Framework. There are two flavors of API in the same domain and are specialized for different scenarios but overlap in a lot of ways. But in the case of TPL & Rx they are actually aware of each other and there are built-in adapters to compose applications and use both frameworks together (like feeding results from a PLINQ loop into an IObservable Rx stream). For the folks who haven't done any parallel programming there is a ton of learning to get up to speed.

Update: I've been using both TPL and RxNet in my regular work for the past 6 months (of the 18 months since my original answer). My thoughts of choice of TPL and/or RxNet in a middle-tier WCF service (enterprise LOB service): http://yzorgsoft.blogspot.com/2011/09/middle-tier-tpl-andor-rxnet.html

참고URL : https://stackoverflow.com/questions/2138361/how-do-reactive-framework-plinq-tpl-and-parallel-extensions-relate-to-each-oth

반응형