문제

비디오 프레임의 실시간 처리를 수행하기 위해 이미지 처리 프로그램을 작성하고 있습니다. OpenCV 라이브러리 DLL (관리되지 않은 C ++)을 감싸는 emgu.cv 라이브러리 (C#)를 사용하여 C#에 있습니다. 이제 내 자신의 특별 알고리즘을 작성해야하며 가능한 빨리 있어야합니다.

알고리즘의 빠른 구현은 무엇입니까?

  1. C#에서 '안전하지 않은'기능 작성

  2. OpenCV 라이브러리에 기능을 추가하고 emgu.cv를 통해 호출

C# 안전하지 않은 것이 JIT 컴파일러를 통과하기 때문에 속도가 느립니다. 그러나 차이가 중요할까요?

편집하다:

VS2008에 따라 .NET 3.5 용으로 편집되었습니다

도움이 되었습니까?

해결책

가능한 빨리 있어야합니다

그런 다음 잘못된 질문을합니다.

지원하는 각 중요한 아키텍처 변형에 대해 다른 버전으로 어셈블러로 코딩하십시오.

가이드로 사용하여 최적화가있는 좋은 C ++ 컴파일러의 출력을 사용하십시오. 아마도 당신이 모르는 트릭을 알고 있기 때문입니다. 그러나 C ++가 반드시 최적화에 유용 할 수있는 모든 정보를 컴파일러에 전달하는 것은 아니기 때문에 일부 개선 사항을 생각할 수있을 것입니다. 예를 들어 C ++에는 C99 키워드가 제한되지 않습니다. 이 경우에도 많은 C ++ 컴파일러 (MSVC 포함)가 이제 지원하므로 가능한 경우 사용하십시오.

물론, "나는 그것이 빠르기를 원하지만 C# 또는 C ++ 외부로 나가는 정도까지는 그렇지 않기를 원하지만"라고 말하면 답은 다릅니다.

나는 C#이 적어도 많은 경우에 유사한 C ++의 성능에 접근 할 것으로 기대합니다. 물론 프로그램이 JIT 자체가 취하는 시간이 관련이 없을 정도로 오래 실행될 것이라고 가정하지만 많은 비디오를 처리하는 경우 가능성이 높습니다. 그러나 안전하지 않은 C#에서 수행하면 C ++의 동등한 것보다 훨씬 느리게 될 것입니다. Jits에 대한 모든 경험이 CLR이 아닌 Java에 있기 때문에 그들이 무엇인지 모르겠습니다. 예를 들어 알고리즘이 C# 코드로 다시 호출되는 경우 C ++에서 느린 것도있을 수 있습니다.

불행히도 그것이 얼마나 가까운 지 확인하는 유일한 방법은 둘 다를 쓰고 테스트하는 것입니다. C ++ 버전을 작성하는 것이 추가 노력이라는 점을 놓치게됩니다. 그러나 반드시 모든 작업을 수행하거나 올바르게 얻지 않고 원하는 처리에 근접한 빠른 코드를 해킹하여 대략적인 아이디어를 얻을 수 있습니다. 알고리즘이 모든 픽셀을 통해 루프를하고 픽셀 당 몇 개의 FP OPS를 수행하는 경우 거친 벤치 마크를 해킹하는 데 30 분이 걸립니다.

보통 나는 "이것은 가능한 한 빠르야한다"고 생각하는 것을 조언 할 것입니다. 요구 사항을 달성 할 수 있어야하며 정의에 따라 "가능한 한 x"는 경계선 만 달성 할 수 있습니다. 요구 사항도 테스트 할 수 있어야하며 "가능한 한 x로"이론적 인 최대 값을 알지 않으면 테스트 할 수 없습니다. 보다 우호적 인 요구 사항은 "이러한 속도 CPU에서 실시간으로 그러한 해상도의 비디오 프레임을 처리해야합니다"또는 "이것은 메인 경쟁 업체의 제품보다 빠르게 필요합니다"입니다. C# 버전이이를 수행하면 사용자 설정에서 예상치 못한 사소한 문제를 설명하기 위해 약간의 여유가 있으면 작업이 완료되었습니다.

다른 팁

알고리즘, 구현, C ++ 컴파일러 및 JIT 컴파일러에 따라 다릅니다. 대부분의 경우 C ++ 구현이 더 빨라질 것이라고 생각합니다. 그러나 이것은 변할 수 있습니다.

JIT 컴파일러는 C ++ 컴파일러와 같이 코드가 실행할 수있는 모든 플랫폼의 평균 대신 코드가 실행중인 플랫폼에 대한 코드를 최적화 할 수 있습니다. 이것은 JIT 컴파일러의 최신 버전이 점점 더 능숙하고 경우에 따라 JITTED 코드에 이점을 줄 수 있습니다. 따라서 대답은 예상만큼 명확하지 않습니다. 예를 들어 새로운 Java 핫스팟 컴파일러가이를 잘 수행합니다.

관리 코드가 C ++보다 더 잘 수행 될 수있는 다른 상황은 많은 작은 개체를 할당하고 거래 해야하는 곳입니다. .NET 런타임은 재사용 할 수있는 큰 메모리 덩어리를 조사하여 메모리를 할당해야 할 때마다 OS로 호출 할 필요가 없습니다.

안전하지 않은 C#이 일반 C#보다 훨씬 빠르게 실행되는지 잘 모르겠습니다. 당신은 이것도 시도해야합니다.

상황에 가장 적합한 솔루션이 무엇인지 알고 싶다면 둘 다 시도하고 차이를 측정해야합니다. 나는 그 이상이있을 것이라고 생각하지 않습니다

C#은 일반적으로 C ++보다 느립니다. 관리 코드에 런타임 확인이 있습니다. 이것들은 결국 그것을 관리하는 것입니다. C ++는 예를 들어 배열의 한계를 초과했는지 확인할 필요가 없습니다.

내 경험을 통해 고정 메모리를 사용하면 많은 도움이됩니다. 새로운 것이 있습니다 System.io.unmanagedMemoryAccessor .NET 4.0의 클래스는 향후 도움이 될 수 있습니다.

언어에는 "속도"가 없습니다. 컴파일러와 코드에 따라 다릅니다. 어떤 언어로든 비효율적 인 코드를 작성할 수 있으며 영리한 컴파일러는 소스의 언어에 관계없이 거의 최적의 코드를 생성합니다.

C#과 C ++ 사이의 성능에서 실제로 피할 수없는 요소는 C# 앱이 시작시 더 많은 작업을 수행해야한다는 것입니다 (.NET 프레임 워크를로드하고 일부 코드를 JIT). 그 후에는 의존하며, 한 언어가 항상 다른 언어보다 더 빠르야하는 근본적인 이유는 없습니다.

또한 안전하지 않은 C#이 안전보다 빠른 이유는 알지 못합니다. 일반적으로 안전은 컴파일러가 훨씬 더 강한 가정을 만들 수 있고 안전합니다. ~할 것 같다 더 빨리하십시오. 그러나 다시, 컴파일중인 코드, 사용중인 컴파일러 및 수십 개의 다른 요소에 따라 다릅니다.

요컨대, 언어의 성능을 측정 할 수 있다는 아이디어를 포기하십시오. 당신은 할 수 없습니다. 언어는 결코 "빠르거나 느리게"가 아닙니다. 속도가 없습니다.

알고리즘을 표준 방식으로 구현하려는 경우 관련이 있다고 생각합니다. 그러나 일부 언어는 API 또는 라이브러리에 구속력이있어서 비 스탠드 부스트를 제공 할 수 있습니다.

  1. GPU 처리를 사용할 수 있는지 고려하십시오 -Nvidia와 ATI는 CUDA 및 CTM 프레임 워크를 제공하며 Khronos Group (OpenGL)의 지속적인 독립 노력이 있습니다. 직감은 AMD가 향후 칩에 하나 이상의 스트리밍 프로세서 코어를 추가 할 것이라고 말합니다. 그래서 나는 그 분야에 상당한 약속이 있다고 생각합니다.

  2. SSE 지침을 이용할 수 있는지 확인하십시오. C ++ 또는 C-에는 편리한 API를 제공하는 라이브러리가 있으며, "Intel Performance Primitives"및 "Math Kernel"을 기억합니다.

그러나 정치 측면에서는 OpenCV에 알고리즘을 통합하여 다른 사람들도 혜택을 줄 수 있습니다.

영원히 분노 할 전투입니다. C 대 C ++ 대 C# 대 뭐든지. C#에서 안전하지 않은 개념은 "위험한"작업을 잠금 해제하는 것입니다. 즉, 포인터 사용 및 C 및 C ++에서 가능한 것처럼 공허 포인터 등에 캐스트 할 수 있습니다. 매우 위험하고 매우 강력합니다! 그러나 C#이 기반으로 한 것을 물리칩니다.

요즘 Microsoft는 특히 .NET가 릴리스 된 이후 성능 방향을 진전 시켰으며 다음 버전의 .NET은 C ++와 마찬가지로 실제로 인라인 메소드를 지원할 것임을 알 수 있습니다. 이것은 매우 구체적인 상황에서 성능을 향상시킵니다. 나는 그것이 AC# 기능이되지 않을 것이라는 것이 싫지만 컴파일러가 픽업하는 불쾌한 속성이지만 모든 것을 가질 수는 없습니다.

개인적으로, 나는 C#과 Managed DirectX (이 게시물의 범위를 넘어서는 이유가 아닌 이유)로 게임을 작성하고 있습니다. 그래픽 상황에서 안전하지 않은 코드를 사용하고 있습니다.이 코드는 다른 사람들이 말한 방향으로 고개를 끄덕입니다.

GDI ++로 픽셀 액세스가 매우 느리기 때문에 대안을 찾기 위해 운전했기 때문입니다. 그러나 전체적으로 C# 컴파일러는 상당히 저렴하며 코드 비교 (기사를 찾을 수 있음)의 경우 성능이 C ++와 매우 비슷하다는 것을 알게됩니다. 그것은 코드를 작성하는 더 좋은 방법이 없다고 말하는 것이 아닙니다.

하루가 끝나면 개인적으로 C, C ++ 및 C#을 실행할 때 거의 같은 속도로 봅니다. 그것은 당신이 기본 하드웨어와 실제로 밀접하게 협력하거나 픽셀에 매우 가깝게 일하고 싶어하는 일부 고통스러운 상황에서 C/C ++ 군중에게 눈에 띄는 이점을 얻을 수 있습니다.

그러나 비즈니스와 오늘날 대부분의 것들에게는 C#은 실제 경쟁자이며 "안전한"환경에 머무르는 것은 확실히 보너스입니다.
밖으로 나갈 때, 당신은 내가 가지고있는 것처럼 안전하지 않은 코드로 대부분의 일을 할 수 있습니다. 그러나 그만한 가치가 있었습니까? 아마 그렇지 않을 것입니다. 나는 개인적으로 C ++의 시간 크리티컬 코드 라인을 따라 더 많이 생각 해야하는지 궁금합니다. 그러나 나는 내가 생각했던 것보다 더 나은 성능을 가지고 있습니다!

당신이 만들고있는 Interop 통화의 양에주의를 기울이는 한 두 세계를 최대한 활용할 수 있습니다. 나는 개인적으로 그것을 피했지만 어떤 비용을 모른다.

그래서 내가 시도하지 않았지만 실제로 C ++를 사용하여 모험을 듣고 싶어요. 그것의 기본 C ++ 컴파일 코드와 어떻게 비교됩니까? 이제 질문이 있습니다!

흠..

환경을 알고 있고 좋은 컴파일러를 사용하는 경우 (Windows에서 비디오 처리를 위해, Intel C ++ 컴파일러가 최선의 선택 일 것입니다) C ++는 여러 가지 이유로 C# 핸드 다운을 이길 것입니다.

  • C ++ 런타임 환경에는 본질적인 런타임 점검이 없습니다 (단점은 자신을 폭파 할 수있는 자유 통치가 있다는 것). C# 런타임 환경은 적어도 처음에는 정신적 검사가 진행될 것입니다.
  • C ++ 컴파일러는 코드 최적화를 위해 구축되었습니다. ICC (또는 GCC)가 사용하는 모든 최적화 Voodo를 사용하여 C# JIT 컴파일러를 구현하는 것이 이론적으로 가능하지만 Microsoft의 JIT가 확실하게 더 잘할 것이라는 것은 의심의 여지가 있습니다. JIT 컴파일러에 런타임 통계가 있더라도 ICC 또는 GCC에서 프로파일 유도 최적화만큼 좋지 않습니다.
  • C ++ 환경을 통해 메모리 모델을 훨씬 더 잘 제어 할 수 있습니다. 애플리케이션이 데이터 캐시를 스래싱하거나 힙을 조각하는 지점에 도달하면 할당에 대한 추가 제어에 정말 감사합니다. 도대체, 동적 할당을 피할 수 있다면 이미 훨씬 나아졌습니다 (힌트 : 실행 시간 malloc() 또는 다른 동적 할당자는 비 결정적이며, 거의 모든 비 원어민 언어는 더 많은 힙 사용을 강요하므로 더 무거운 할당).

열악한 컴파일러를 사용하거나 좋은 칩셋을 타겟팅 할 수없는 경우 모든 베팅이 꺼져 있습니다.

나는 조금 늦었지만 일화적인 경험을 줄 수 있습니다. 포인터와 안전하지 않은 코드를 사용하여 원래 C#로 코딩 된 매트릭스 곱셈 루틴이있었습니다. 이것은 우리의 응용 프로그램에서 병목 현상으로 판명 된 다음 Pinning+P/Invoke를 사용하여 C ++ 버전의 행렬 곱셈 루틴으로 호출했으며 2의 요인이 2의 개선을 받았습니다. 이것은 .NET 1.1이 있는데 시간이 오래 걸렸으므로 지금은 더 나을 것입니다. 다른 사람들이 지적했듯이, 이것 증명합니다 아무것도 아니지만 흥미로운 운동이었습니다.

또한 알고리즘이 실제로 "가능한 한 빠른"IPL을 활용해야하거나 GPU 구현을 고려해야한다면 Thaaanos에 동의합니다.

솔직히 말해서, 어떤 언어를 작성하는지는 어떤 알고리즘을 사용하는지 (어쨌든)만큼 중요하지 않습니다. 아마도 네이티브 코드로 이동하여 ~할 것 같다 응용 프로그램을 더 빨리 만들지 만 느리게 만들 수 있습니다. 컴파일러, 프로그램 작성 방법, 혼합 환경을 사용하는 경우 발생하는 인터 로프 비용의 종류 등에 따라 다릅니다. '실제로 프로파일 링하지 않고 말합니다. (그리고 그 문제에 대해 신청서를 프로파일 링 했습니까? 실제로 시간을 보내는 곳을 알고 있습니까?)

더 나은 알고리즘은 선택한 언어와 완전히 독립적입니다.

CPU에서 실행하는 것은 CPU의 VM에서 실행하는 것보다 항상 빠릅니다. 나는 사람들이 다른 논쟁을 시도하고 있다고 믿을 수 없다.

예를 들어, 웹 서버에서 대기하는 상당히 무거운 이미지 처리 작업이 있습니다. 처음에는 IT 작동을 위해 PHP의 GD 기능을 사용했습니다.

그들은 지옥처럼 느 렸습니다. C ++에서 필요한 기능을 다시 작성했습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top