나는 모든 대답이 없습니다. 잘만되면 나는 그것에 약간의 빛을 비출 수 있다.
.NET의 스레딩 모델에 대한 이전의 설명을 단순화하려면 Parallel Library가 Tasks를 사용하고 Task의 기본 TaskScheduler가 ThreadPool을 사용한다는 것을 알고 있습니다. 계층 구조에서 높을수록 (ThreadPool이 맨 아래에 있음) 항목을 만들 때 더 많은 오버 헤드가 발생합니다. 그 여분의 오버 헤드가 확실히 느리다는 것을 의미하지는 않지만 그것이 있다는 것을 아는 것이 좋습니다. 궁극적으로 다중 스레드 환경에서 알고리즘의 성능은 설계에 따릅니다. 순차적 으로 잘 수행되는 것은 병렬로 잘 수행되지 않을 수 있습니다 . 어렵고 빠른 규칙을 제공하기에는 너무 많은 요소가 관련되어 있으며, 수행하려는 작업에 따라 변경됩니다. 네트워크 요청을 다루기 때문에 간단한 예를 들어 보겠습니다.
소켓 전문가가 아니라고 Zeroc-Ice에 대해 아는 것이 없습니다. 비동기 작업에 대해 조금 알고 있으며 이것이 실제로 도움이 될 것입니다. 소켓을 통해 동기 요청을 보내면을 호출 Socket.Receive()
하면 요청이 수신 될 때까지 스레드가 차단됩니다. 이건 좋지 않아 스레드가 차단되어 더 이상 요청을 할 수 없습니다. Socket.Beginxxxxxx ()를 사용하면 I / O 요청이 이루어지고 소켓의 IRP 대기열에 저장되며 스레드는 계속 진행됩니다. 즉, 스레드가 실제로 차단없이 수천 개의 요청을 루프로 만들 수 있습니다!
내가 당신을 올바르게 이해한다면 테스트 코드에서 Zeroc-Ice를 통한 호출을 사용하고 실제로 http 끝점에 도달하려고하지 않습니다. 이 경우 Zeroc-Ice의 작동 방식을 모른다는 것을 인정할 수 있습니다. 그러나 여기 에 나열된 조언 , 특히 부분을 따르는 것이 좋습니다 Consider Asynchronous Method Invocation (AMI)
. 이 페이지는 이것을 보여줍니다 :
AMI를 사용하면 클라이언트는 호출이 전송 되 자마자 (또는 즉시 전송 될 수없는 경우 대기열에 놓인 즉시) 제어 스레드를 다시 확보하여 클라이언트가 해당 스레드를 사용하여 그 동안 다른 유용한 작업을 수행 할 수 있도록합니다. .
.NET 소켓을 사용하여 위에서 설명한 것과 동등한 것 같습니다. 많은 전송을 시도 할 때 성능을 향상시키는 다른 방법이있을 수 있지만 여기서 시작하거나 해당 페이지에 나열된 다른 제안으로 시작합니다. 귀하는 응용 프로그램의 디자인에 대해 매우 모호하여 위의 것보다 더 구체적 일 수 있습니다. 꼭 필요한 것을 얻는 데 꼭 필요한 것보다 많은 스레드를 사용하지 마십시오 . 그렇지 않으면 응용 프로그램이 원하는 것보다 훨씬 느리게 실행될 수 있습니다.
의사 코드의 일부 예 (실제로 그것을 배우지 않고도 가능한 한 얼음에 가깝게 만들려고 시도했습니다) :
var iterations = 100000;
for (int i = 0; i < iterations; i++)
{
// The thread blocks here waiting for the response.
// That slows down your loop and you're just wasting
// CPU cycles that could instead be sending/receiving more objects
MyObjectPrx obj = iceComm.stringToProxy("whateverissupposedtogohere");
obj.DoStuff();
}
더 좋은 방법 :
public interface MyObjectPrx : Ice.ObjectPrx
{
Ice.AsyncResult GetObject(int obj, Ice.AsyncCallback cb, object cookie);
// other functions
}
public static void Finished(Ice.AsyncResult result)
{
MyObjectPrx obj = (MyObjectPrx)result.GetProxy();
obj.DoStuff();
}
static void Main(string[] args)
{
// threaded code...
var iterations = 100000;
for (int i = 0; i < iterations; i++)
{
int num = //whatever
MyObjectPrx prx = //whatever
Ice.AsyncCallback cb = new Ice.AsyncCallback(Finished);
// This function immediately gets called, and the loop continues
// it doesn't wait for a response, it just continually sends out socket
// requests as fast as your CPU can handle them. The response from the
// server will be handled in the callback function when the request
// completes. Hopefully you can see how this is much faster when
// sending sockets. If your server does not use an Async model
// like this, however, it's quite possible that your server won't
// be able to handle the requests
prx.GetObject(num, cb, null);
}
}
소켓을 보내려고 할 때 (또는 실제로 무언가를 할 때) 더 많은 스레드! = 더 나은 성능을 명심하십시오. 스레드는 작업중 인 모든 문제를 자동으로 해결한다는 점에서 마술이 아닙니다. 스레드가 대기하는 데 많은 시간을 소비하지 않는 한 코어 당 1 개의 스레드를 원하는 것이 이상적입니다. 컨텍스트 전환이 발생하고 리소스가 낭비되므로 각 요청을 자체 스레드에서 실행하는 것은 좋지 않습니다. (내가 쓴 모든 내용을 보려면 편집을 클릭 하고이 게시물의 과거 개정판을 살펴보십시오. 주요 문제 만 흐리게 보이기 때문에 제거했습니다.)
초당 많은 수의 요청을하려면 스레드에서 이러한 요청을 확실히 수행 할 수 있습니다. 그러나 쓰레드 생성으로 오버 보드하지 마십시오. 균형을 찾아서 고수하십시오. 비동기 모델과 동기 모델을 사용하면 성능이 향상됩니다.
도움이 되길 바랍니다.