Pergunta

Eu estou escrevendo um programa de processamento de imagem para executar processamento em tempo real de quadros de vídeo. É em C # usando a biblioteca Emgu.CV (C #) que envolve o dll biblioteca OpenCV (não gerenciado C ++). Agora eu tenho que escrever meu próprio algoritmo especial e ele precisa ser tão rápido quanto possível.

Qual será uma implementação mais rápida do algoritmo?

  1. Escrevendo uma função de 'inseguro' em C #

  2. Como adicionar a função para a biblioteca OpenCV e chamando-o através Emgu.CV

Eu estou supondo C # inseguro é mais lento porque vai throught o compilador JIT, mas a diferença é significativa?

Editar:

compilado para NET 3.5 sob VS2008

Foi útil?

Solução

ele precisa ser tão rápido quanto possível

Em seguida, você está fazendo a pergunta errada.

Código lo em assembler, com versões diferentes para cada variante arquitetura significativa lhe apoio.

Use como guia a saída de um bom compilador C ++ com a otimização, porque ele provavelmente conhece alguns truques que você não faz. Mas você provavelmente vai ser capaz de pensar de algumas melhorias, porque C ++ não necessariamente transmitir para o compilador todas as informações que possam ser úteis para a otimização. Por exemplo, C ++ não tem a palavra-chave C99 restringir. Embora nesse caso particular, muitos compiladores C ++ (incluindo MSVC) que agora apoiá-lo, para usá-lo sempre que possível.

É claro que se você quer dizer, "eu quero que seja rápido, mas não a ponto de ir para fora C # ou C ++", então a resposta é diferente; -)

Eu esperaria C # para pelo menos abordagem o desempenho do C de aparência semelhante ++ em muitos dos casos. Presumo é claro que o programa será executado tempo suficiente para que o tempo do próprio JIT leva é irrelevante, mas se você está processando tanto de vídeo, em seguida, que parece provável. Mas eu também esperar que haja certas coisas que se você fazê-las em inseguro C #, será muito mais lento do que a coisa equivalente em C ++. Eu não sei o que são, porque toda a minha experiência de EIC é em Java em vez de CLR. Também pode haver coisas que são mais lento em C ++, por exemplo, se o seu algoritmo faz qualquer chamada de volta em código C #.

Infelizmente a única maneira de ter certeza de quão próximo está é escrever tanto e testá-los, que tipo de perde o ponto que escrever o C ++ versão é um monte de esforço extra. No entanto, você pode ser capaz de ter uma idéia cortando algum código rápida que se aproxima o processamento que você quer fazer, sem necessariamente fazer tudo isso ou fazê-lo direito. Se você algoritmo vai loop sobre todos os pixels e fazer algumas ops FP por pixel, em seguida, cortar juntos uma referência grosseira deve tomar todas de meia hora.

Normalmente, gostaria de aconselhar contra começando a pensar "Isso precisa ser o mais rápido possível". Os requisitos devem ser alcançáveis, e por definição "como X quanto possível" única fronteira viável é. Requisitos também deve ser testável, e "como X quanto possível" não é testável, a menos que você de alguma forma conhecer um máximo teórico. Um requisito mais amigável é "Isto precisa de quadros de vídeo processo de tal e tal resolução em tempo real sobre tal e tal CPU velocidade a", ou "Isso precisa ser mais rápido do que o produto nosso principal concorrente". Se o C # versão faz isso, com um pouco de sobra para conta para pequenos problemas inesperados na configuração do usuário, em seguida, trabalho feito.

Outras dicas

Depende do algoritmo, a implementação, o compilador C ++ e o compilador JIT. Eu acho que na maioria dos casos a aplicação do C ++ será mais rápido. Mas isso pode mudar.

O compilador JIT pode otimizar o seu código para a plataforma de seu código está sendo executado em vez de uma média para todas as plataformas seu código pode executar em como o compilador C ++ faz. Esta é versões algo mais recentes do JIT compilador estão cada vez mais bom e pode, em alguns casos dão código JITted uma vantagem. Portanto, a resposta não é tão clara como você poderia esperar. O novo compilador Java hotspot faz isso muito bem, por exemplo.

Outras situações em que o código gerenciado pode fazer melhor do que C ++ é onde você precisa para alocar e desalocar lotes de pequenos objetos. O .NET runtime pré-aloca grandes blocos de memória que pode ser reutilizado por isso não precisa de chamada para o sistema operacional cada vez que você precisa alocar memória.

Eu não tenho certeza inseguro C # corre muito mais rápido do que o normal C #. Você vai ter que tentar isso também.

Se você quer saber qual é a melhor solução para a sua situação, você vai ter que tentar ambos e medir a diferença. Eu não acho que haverá mais de

C # é tipicamente mais lento do que C ++. Há verificações de tempo de execução em código gerenciado. Estes são o que tornam conseguiu, depois de tudo. C ++ não tem que verificar se os limites de uma matriz foram ultrapassados ??por exemplo.

Da minha experiência, usando memória fixa ajuda muito. Há um novo System.IO.UnmanagedMemoryAccessor classe em .NET 4.0 que pode ajudar no futuro.

Idiomas não tem uma "velocidade". Depende do compilador e o código. É possível escrever código ineficiente em qualquer língua, e um compilador inteligente irá gerar o código perto do ideal não importa a linguagem da fonte.

O único fator realmente inevitável no desempenho entre C # e C ++ é que C # aplicações têm de fazer mais na inicialização (carregar o framework .NET e talvez JIT algum código), então todas as coisas são iguais, eles vão lançar um pouco mais lento. Depois disso, ele depende, e não há nenhuma razão fundamental para que uma língua deve ser sempre mais rápido do que o outro.

Eu também não estou ciente de quaisquer razões pelas quais inseguro C # deve ser mais rápido do que seguro. Em geral, o cofre é bom porque permite que o compilador para fazer algumas suposições muito mais forte, e tão seguro pode ser mais rápido. Mas, novamente, depende do código que você está compilando, o compilador que você está usando e uma dúzia de outros fatores.

Em suma, dar-se na idéia de que você pode medir o desempenho de uma língua. Você não pode. A língua nunca é "rápido" ou lento". Ele não tem a velocidade.

Se você estiver indo para implementar seu algoritmo de uma forma padrão Eu acho que é irrelevante. Mas algumas línguas têm ligações para apis ou bibliotecas que podem dar-lhe um impulso não Standart.

  1. Considere se você pode usar o processamento GPU - nvidia e ati fornecer os quadros CUDA e CTM e há um esforço padronização em curso do Khronos Group (OpenGL). Um palpite me diz também que a AMD irá adicionar pelo menos um núcleo do processador de streaming em suas futuras fichas. Então eu acho que há muito uma promessa nessa área.

  2. Tente ver se você pode explorar instruções SSE, existem bibliotecas em torno -mais em C ++ ou C que fornecem apis úteis, verifique o site da Intel para bibliotecas otimizadas à mão Eu me lembro "Intel Performance Primitives" e um " Math Kernel".

Mas no lado da política, não incorporar o seu algoritmo em OpenCV para que outros possam beneficiar também.

É uma batalha que irá assolar para sempre. C contra C contra C # ++ contra o que quer. Em C #, a noção de inseguro é para desbloquear operações de "perigosos". ou seja, o uso de ponteiros, e ser capaz de elenco para ponteiros void etc, como você pode em C e C ++. Muito perigoso, e muito poderoso! Mas derrotar o C # foi baseado.

Você verá que avanços nos dias de hoje, a Microsoft fez na direção de desempenho, especialmente desde o lançamento do .NET, ea próxima versão do .NET vai realmente apoiar métodos in-line, como você pode com C ++. Isto irá aumentar o desempenho para situações muito específicas. Eu odeio que ele não vai ser uma característica c #, mas um atributo desagradável o compilador capta - mas você não pode ter tudo

.

Pessoalmente, eu estou escrevendo um jogo com C # e conseguiu DirectX (por que não XNA ?? além do escopo deste post). Eu estou usando o código inseguro em situações gráficas, que traz um aceno na direção do que outros já disseram.

É apenas porque o acesso pixel é ridiculamente lento, com GDI ++ que eu estava levados a procurar alternativas. Mas, no geral, o compilador C # é muito danado de bom, e para comparações de código (você pode encontrar artigos) você encontrará o desempenho é muito comparável ao c ++. Isso não quer dizer que não é a melhor maneira de escrever o código.

No final do dia, eu pessoalmente ver C, C ++ e C # como sobre a mesma velocidade durante a execução. É só que em algumas situações dolorosas onde quer trabalhar muito estreitamente com o hardware subjacente ou muito próximo a esses pixels, que você vai encontrar vantagem perceptível para multidão o C / C ++.

Mas para negócios, e a maioria das coisas hoje em dia, C # é um candidato real, e ficar dentro do ambiente "seguro" é definitivamente um bônus.
Quando pisar fora, você pode obter a maioria das coisas feitas com código inseguro, como eu tenho - e boy, tenho ido a alguns extremos! mas valeu a pena? Provavelmente não. Eu, pessoalmente, me pergunto se eu deveria ter pensado mais ao longo das linhas de código de tempo crítico em C ++, e toda a Object Oriented material seguro em C #. Mas eu tenho um melhor desempenho do que eu pensei que eu ia conseguir!

Enquanto você tiver cuidado com a quantidade de interoperabilidade exige que você está fazendo, você pode obter o melhor dos dois mundos. Eu tenho evitado pessoalmente isso, mas eu não sei a que custo.

Assim, uma abordagem que eu não tentei, mas gostaria de ouvir aventuras, na verdade usando C ++ NET para desenvolver uma biblioteca em -. Teria que ser mais rápido do que c # 's perigoso para estas situações gráficas especiais? Como isso se compara com o código C ++ compilado nativo? Agora há uma pergunta!

Hmm ..

Se você conhece o seu ambiente e você usar um bom compilador (para processamento de vídeo no Windows, Intel C ++ Compiler é provavelmente a melhor escolha), C ++ vai bater C # mãos para baixo por várias razões:

  • A C ++ ambiente de execução não tem tempo de execução verifica intrínsecas (a desvantagem é que você tem total liberdade para explodir-se). O ambiente de tempo de execução C # vai ter alguma sanidade verificar acontecendo, pelo menos inicialmente.
  • compiladores C ++ são construídos para otimização de código. Embora seja teoricamente possível implementar um C # compilador JIT usando todo o voodo otimização que ICC (ou GCC) usos, é duvidoso que JIT da Microsoft vai confiantemente fazer melhor. Mesmo se o compilador JIT tem estatísticas de tempo de execução, que ainda não é tão bom como otimização guiada por perfil em qualquer ICC ou GCC.
  • Um ambiente C ++ permite que você controlar o seu modelo de memória muito melhor. Se o seu pedido chega ao ponto de debulhar o cache de dados ou fragmentação da pilha, você vai realmente apreciar o controle extra sobre alocação. Heck, se você pode evitar alocações dinâmicas, você já está muito melhor (dica: o tempo de execução de malloc() ou qualquer outro alocador dinâmico é não determinístico, e quase todas as línguas não-nativas forçar o uso mais pesado montão, e, portanto, a alocação mais pesado).

Se você usar um compilador pobres, ou se você não pode ter como alvo um bom chipset, todas as apostas estão fora .

Eu sou um pouco tarde em responder, mas posso dar-lhe alguma experiência anedótica. Tivemos algumas rotinas de multiplicação de matrizes que foram originalmente codificados em C # usando ponteiros e código inseguro. Isto provou ser um gargalo em nossa aplicação e, em seguida, usado fixando + P / Invoke para pôr em uma versão C ++ da rotina de multiplicação Matrix e tem um fator de 2 melhoria. Este foi um tempo atrás com .NET 1.1, então as coisas poderiam ser melhor agora. Como outros apontam, este comprova nada, mas era um exercício interessante.

Também concordo com thAAAnos, se algoritmo realmente tem que ser "o mais rápido possível" alavancagem IPL ou, se for necessário, considerar uma implementação GPU.

Para ser honesto, o idioma que você escrevê-lo em não é quase tão importante quanto o que você usa algoritmos (IMO, de qualquer maneira). Talvez por ir para código nativo você pode tornar a sua aplicação mais rápida, mas também pode torná-lo mais lento - it'd depender do compilador, como os programas são escritos, que tipo de interoperabilidade que você custa' d incorrer se você estiver usando um ambiente misto, etc. você não pode realmente dizer sem perfilar-lo. (E, para essa matéria, você tem perfilado seu aplicativo? Você realmente sabe onde ele está gastando tempo? )

A melhor algoritmo é completamente independente do idioma que você escolher.

Correndo na CPU é sempre vai ser mais rápido do que correr em uma VM na CPU. Não posso acreditar que as pessoas estão tentando argumentar o contrário.

Por exemplo, nós temos algum trabalho de processamento de imagem bastante pesado em nosso servidor web que da fila. Inicialmente para fazê-lo funcionar, usamos funções GD do PHP.

Eles foram lento como o inferno. Nós reescrevemos a funcionalidade que precisávamos em C ++.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top