Pergunta

Estou planejando participar do desenvolvimento de um código escrito em C Language for Monte Carlo Análise de problemas complexos. Esses códigos alocam enormes matrizes de dados na memória para acelerar seu desempenho; portanto, o autor do código escolheu C em vez de C ++ alegando que se pode tornar o código mais rápido e confiável (sobre vazamentos de memória) com C.

Você concorda com aquilo? Qual seria a sua escolha, se você precisar armazenar 4-16 GB de matrizes de dados na memória durante o cálculo?

Foi útil?

Solução

Definitivamente C ++. Por padrão, não há diferença significativa entre os dois, mas O C ++ fornece algumas coisas C não:

  1. construtores/destruidores. Isso permite automatizar a maior parte do gerenciamento de memória, melhorando a confiabilidade.
  2. Alocadores por classe. Isso permite otimizar a alocação com base em como objetos específicos são projetados e/ou usados. Isso pode ser particularmente útil se você precisar de um grande número de objetos pequenos (para dar um exemplo óbvio).

A linha inferior é que, a esse respeito, C não oferece absolutamente nenhuma possibilidade de uma vantagem sobre o C ++. Na pior das hipóteses, você pode fazer exatamente as mesmas coisas da mesma maneira.

Outras dicas

Há uma característica do C99 ausente do C ++ e que potencialmente fornece ganhos de velocidade significativos no código de acidente de número pesado, e isso é palavra-chave restrict. Se você pode usar um compilador C ++ que o suporta, terá uma ferramenta extra no kit quando se trata de otimizar. É apenas um ganho potencial: porém: inline o suficiente pode permitir as mesmas otimizações que restrict e mais. Também não tem nada a ver com alocação de memória.

Se o autor do código puder demonstrar uma diferença de desempenho entre o código C e C ++ alocando uma matriz de 4-16 GB, então (a) fico surpreso, mas ok, há uma diferença e (b) quantos vezes O programa vai alocar matrizes tão grandes? O seu programa é realmente gastar uma quantidade significativa de seu tempo alocando memória ou está gastando a maior parte do tempo Acessando memória e fazendo cálculos? Leva muito tempo para realmente Faz Qualquer coisa com uma matriz de 4 GB, em comparação com o tempo necessário para alocar, e isso significa que você deve se preocupar com o desempenho de "qualquer coisa", não com o desempenho da alocação. Os velocistas se preocupam muito com a rapidez com que saem dos blocos. Corredores de maratona, nem tanto.

Você também deve ter cuidado com a referência. Você deveria estar comparando, por exemplo malloc(size) contra new char[size]. Se você testar malloc(size) contra new char[size]() Então é uma comparação injusta, já que o último define a memória para 0 e o primeiro não. Comparar contra calloc Em vez disso, mas também observe que malloc e calloc estão disponíveis no C ++ no evento (improvável) que eles provam mensurávelmente mais rápido.

Por fim, porém, se o autor "possui" ou inicia o projeto, e prefere escrever em C em vez de C ++, ele não deve justificar essa decisão com reivindicações de desempenho provavelmente espúrias, ele deve justificá-lo dizendo "eu prefiro c , e é isso que estou usando ". Geralmente, quando alguém faz uma reivindicação como essa sobre o desempenho do idioma, e acaba nos testes para não ser verdadeira, você descobre que o desempenho não é o verdadeiro motivo da preferência do idioma. Provar que a reivindicação falsa não fará com que o autor deste projeto comece a gostar repentinamente do C ++.

Não há diferença real entre C e C ++ em termos de alocação de memória. O C ++ possui mais dados 'ocultos', como ponteiros virtuais e assim por diante, se você optou por ter métodos virtuais em seus objetos. Mas alocar uma variedade de chars é tão cara em C quanto em C ++, na verdade, provavelmente ambos estão usando o Malloc para fazê -lo. Em termos de desempenho, o C ++ chama um construtor para cada objeto na matriz. Observe que isso só é feito se houver um, o construtor padrão não faz nada e é otimizado.

Desde que você esteja pré -alocando pools de dados, para evitar a fragmentação da memória, você deve estar pronto. Se você tiver estruturas de pod simples sem métodos virtuais e sem construtores, não há diferença.

A única coisa em desfavor de C ++ é a complexidade adicional - Combine isso com um programador que o usa incorretamente e você pode facilmente desacelerar notavelmente. O uso de um compilador C ++ sem recursos C ++ fornecerá o mesmo desempenho. Usando o C ++ corretamente, você tem algumas posições para ser mais rápido.

O idioma não é o seu problema, alocar e atravessar grandes matrizes é.

O principal erro mortal que você pode cometer na alocação (em qualquer idioma) está alocando 16g de memória, inicializando -o para zero, apenas para preenchê -lo com valores reais posteriormente.

Os ganhos mais de desempenho que eu esperaria de otimizações algorítmicas que melhoram a localidade da referência.

Dependendo do sistema operacional subjacente, você também pode afetar os algoritmos de cache - por exemplo, indicando que um intervalo de memroy é processado apenas sequencialmente.

Para alocar dados brutos, não deve haver diferença entre C e C ++ na maioria dos sistemas, pois eles normalmente usam os mesmos mecanismos de biblioteca de tempo de execução. Gostaria de saber se essa foi a armadilha clássica de referência, onde eles também mediram o tempo de execução das chamadas do construtor em C ++ e se esqueceu convenientemente de incluir o tempo de execução de qualquer tipo de código de inicialização em C.

Além disso, o argumento "mais confiável (sobre vazamentos de memória)" não mantém água se você estiver usando RAII em C ++ (como deveria). A menos que alguém esteja se referindo a fazer vazar de maneira mais confiável, usando RAII, ponteiros inteligentes e classes de contêineres reduzirão o potencial de vazamentos, não o aumentarão.

Minhas principais preocupações em alocar que muita memória seria dupla:

  • Se você está chegando perto do limite de memória física nas máquinas em que está executando a simulação de Monte Carlo, é uma boa maneira de diminuir o desempenho, porque o disco pode muito bem começar a bater quando o sistema de memória virtual precisa começar a pagar muito . A memória virtual não é "gratuita", embora muitas pessoas pensem que é.
  • O layout de dados precisa ser cuidadosamente considerado para maximizar o uso do cache do processador; caso contrário, você perderá parcialmente os benefícios de manter os dados na memória principal em primeiro lugar.

Se a alocação de memória for um gargalo nesse código, sugiro o redesenho, não alterando a linguagem para uma alocação mais rápida. Se você alocar memória uma vez e, em seguida, executar muitos cálculos, eu esperaria que esses cálculos fossem um gargalo. Se o custo da alocação for significativo, algo está errado aqui.

Você também pode usar as funções C Família C de Memória em C ++: ambos o padrão malloc e free, realloc para ampliar/encolher matrizes e alloca Para alocar memória na pilha.

Se você for com new, ele alocará mais memória do que é necessário (principalmente durante a depuração) e fará verificações extras para consistência. Ele também chamará o construtor para aulas. Em um lançamento (-O3) Construir a diferença será insignificante para a maioria dos aplicativos.

O que agora new traz esse malloc não é o local new. Você pode pré-alocar um buffer e depois usar o local new Para colocar sua estrutura nesse buffer, tornando -a "alocando" instantânea.

Em suma, eu não ficaria longe de C por causa de preocupações com o desempenho. Se alguma coisa, seu código será mais eficiente porque as classes passam no this ponteiro em registros em vez de parâmetros como no equivalente C. Um motivo real para ficar longe de C é o tamanho do tempo de execução do C ++. Se você desenvolver programas para sistemas incorporados ou programas carregados de inicialização, não poderá incorporar o tempo de execução de ~ 4 MB. Para aplicações normais, no entanto, isso não fará a diferença.

Se você precisar armazenar 4-16 GB de matrizes de dados na memória durante o cálculo e sua máquina possui apenas 2 GB de memória física, então?

E se sua máquina tiver 16 GB de memória física? O sistema operacional não leva a memória física?

O sistema operacional ainda permite um espaço de endereço de 4 GB, 16 GB, etc?

Sugiro que, se o desempenho for uma restrição de implementação primária, compreenda como as plataformas devem ser usadas, a função e o desempenho são muito mais significativos do que a questão de qualquer diferença de desempenho mensurável entre C e C ++, dados ambientes e algoritmos idênticos.

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