Qual a importância da multithreading na atual indústria de software? [fechadas]

59

Tenho quase 3 anos de experiência escrevendo aplicativos Web em Java usando estruturas MVC (como struts). Eu nunca escrevi código multithread até agora, embora tenha escrito código para as principais redes de varejo.

Recebo algumas perguntas sobre multithreading durante as entrevistas e respondo normalmente (principalmente perguntas simples). Isso me deixou imaginando a importância do Multithreading no cenário atual do setor.

user2434
fonte
8
Você pode não ter feito isso explicitamente, mas definitivamente se aproveitou disso nos bastidores.
Martin York
1
Eu raramente trabalho com código multithread para o trabalho, mas tento ler sobre ele / ser capaz de discuti-lo durante uma entrevista. Eu não gostaria de trabalhar com codificadores que não obtêm threads e não gostaria de trabalhar com codificadores que não se importam se outros codificadores obtêm threads.
Job
1
Eu raramente o uso no desenvolvimento web, mas acho que é mais comum em outros lugares. Por exemplo, recentemente escrevi um aplicativo para Android e percebi que você precisa usar multithreading se tiver alguma atividade de rede.
precisa saber é o seguinte
4
Não é importante multithreading, é computação paralela. Se você acha que tudo o que uma solicitação única que leva ao seu aplicativo Web está no encadeamento ... você deve estar fumando alguma coisa.
user606723
1
A capacidade de "pensar fora do encadeamento" é muito boa, mesmo para programação de encadeamento único. Você aceita muito menos, e seu código geralmente é mais robusto e reutilizável.
precisa saber é o seguinte

Respostas:

92

Isso é extremamente importante.

O mais importante, porém, é entender que a multithreading é apenas uma maneira de resolver o problema de assincronia. O ambiente técnico no qual muitas pessoas estão escrevendo software difere do ambiente histórico de desenvolvimento de software (de aplicativos monolíticos que executam cálculos em lote) de duas maneiras principais:

  • Máquinas com muitos núcleos agora são comuns. Não podemos mais esperar que a velocidade do relógio ou a densidade do transistor aumente em ordens de magnitude. O preço da computação continuará caindo, mas cairá por causa de muito paralelismo. Teremos que encontrar uma maneira de tirar proveito desse poder.

  • Agora, os computadores estão fortemente conectados em rede e os aplicativos modernos contam com a capacidade de buscar informações valiosas de várias fontes.

Do ponto de vista computacional, esses dois fatores se resumem essencialmente à mesma idéia central: as informações estarão cada vez mais disponíveis de maneira assíncrona . Se as informações de que você precisa estão sendo computadas em outro chip da sua máquina ou em um chip do outro lado do mundo, não importa. De qualquer maneira, seu processador está sentado lá, queimando bilhões de ciclos por segundo, aguardando informações quando poderia estar fazendo um trabalho útil.

Portanto, o que importa agora, e o que importa ainda mais no futuro, não é multithreading por si só, mas, ao contrário, lidar com assincronia . A multithreading é apenas uma maneira de fazer isso - uma maneira complicada e propensa a erros que só ficará mais complicada e propensa a erros, à medida que os chips com modelo de memória fraca se tornarem mais amplamente utilizados.

O desafio para os fornecedores de ferramentas é apresentar algo muito melhor do que o multithreading para que nossos clientes lidem com a infraestrutura assíncrona que usarão no futuro.

Eric Lippert
fonte
5
+1 para uma excelente resposta, merece mais crédito do que minha humilde tentativa.
Péter Török
2
As informações estarão cada vez mais disponíveis de maneira assíncrona. Se isso não é verdade. . .
surfasb 19/09/11
2
concurrencyé mais importante que o asynchronous comportamento. Você pode ter assincronia sem simultaneidade (isto é, vários threads em uma CPU de núcleo único) asynchronousnão é um substituto semântico concurrency.
5
@Jarrod: Domar a assincronia é mais importante do que apenas domar a simultaneidade exatamente pelo motivo que você menciona: a simultaneidade é apenas um tipo particularmente difícil de assincronia. A parte difícil da simultaneidade não é o aspecto "coisas acontecendo ao mesmo tempo" e, de fato, a simultaneidade é frequentemente apenas simultaneidade simulada , por exemplo, multitarefa não cooperativa por meio do corte de tempo. A parte difícil é usar eficientemente os recursos sem bloquear, travar, travar e sem escrever programas de dentro para fora que são difíceis de raciocinar localmente.
Eric Lippert
"a simultaneidade é frequentemente apenas simultânea simulada, por exemplo, multitarefa não-cooperativa por meio da divisão do tempo": no meu entendimento, essa ainda é (verdadeira) simultaneidade, talvez você queira dizer que não é paralelismo?
Giorgio
46

Está se tornando cada vez mais importante, pois os processadores modernos têm cada vez mais núcleos. Há uma década, a maioria dos computadores existentes tinha apenas um processador; portanto, o multithreading era importante apenas em aplicativos de servidor de última geração. Atualmente, mesmo os laptops básicos possuem processadores multicore. Em alguns anos, até dispositivos móveis ... Então, mais e mais códigos são necessários para usar as vantagens potenciais de desempenho da simultaneidade e executar corretamente em um ambiente multithread.

Péter Török
fonte
3
+1: mais importante do que nunca. Lembre-se também de que, em um design de sistema, você também pode obter os benefícios do multithreading apenas particionando o trabalho para que mais processos o façam.
22611 Scott C Wilson #
11
Alguns dispositivos móveis já possuem processadores com vários núcleos!
Che Jami
3
Eu diria que o multi-threading é importante desde a criação do primeiro sistema de compartilhamento de tempo. Ter vários processadores / núcleos apenas adiciona uma nova dimensão de eficiência a vários threads.
jwernerny
Talvez os threads (especialmente em dispositivos móveis) sejam uma má ideia. O sistema operacional provavelmente deve lidar com a otimização do uso dos núcleos sem que o código do usuário com erro tente executar o encadeamento. Existem muito poucas aplicações que um usuário normal tem acesso a essa necessidade ou se beneficiaria com multidões. A única exceção são (aplicativos gráficos de ponta / ferramentas para desenvolvedores / modelagem climática / servidores da Web (e serviços associados)) todos os aplicativos especializados de ponta.
Martin York
1
@ Tux-D, você pode muito bem ter um jogo em um dispositivo móvel que utiliza mais de um núcleo. Não é algo excepcional.
whitequark
28

Em geral, o multi-threading já é bastante importante e só se tornará mais importante nos próximos anos (como Péter Török) apontou - é como os processadores serão dimensionados para o futuro previsível (mais núcleos em vez de MHz mais alto) .

No seu caso, no entanto, você parece estar trabalhando principalmente com aplicativos da web. Os aplicativos da Web, por natureza, são multiencadeados devido à maneira como o servidor da Web processa solicitações para cada usuário (por exemplo, em paralelo). Embora seja provavelmente importante que você entenda a simultaneidade e a segurança de encadeamentos (especialmente ao lidar com caches e outros dados compartilhados), duvido que você tenha muitos casos em que é benéfico encadear o código de aplicativo da Web internamente (ou seja, vários trabalhadores threads por solicitação). Nesse sentido, acho que ser um especialista em multiencadeamento não é realmente necessário para um desenvolvedor web. É frequentemente solicitado em entrevistas, porque é um assunto bastante complicado, e também porque muitos entrevistadores apenas pesquisam algumas perguntas 10 minutos antes de você chegar lá.

Daniel B
fonte
+1 pela observação de que o pôster é um desenvolvedor da Web e a maioria dos contêineres de servidores da Web faz uma quantidade decente de trabalho com vários threads para você. Não que isso elimine a necessidade em alguns casos, mas 99% das vezes o código do controlador com vários threads não é a maior melhoria de desempenho para uma chamada MVC.
Mufasa 23/09
19

Multi-threading é um arenque vermelho. O multiencadeamento é um detalhe da implementação do problema real, que é simultaneidade . Nem todos os programas encadeados são simultâneos devido a bloqueios e o que não.

Threads são apenas um modelo e padrão de implementação para implementar concurrentprogramas.

Por exemplo, você pode escrever um software altamente escalonável e tolerante a falhas, sem executar multithreading em idiomas como o Erlang.


fonte
+1, embora eu ainda ache que Erlang é multiencadeado; a comunidade redefiniu a palavra "thread" para depender de um estado compartilhado mutável e, assim, se distinguir dele.
Dan
1
a VM do Erlang usa 1 thread por CPU por padrão, mas como desenvolvedor do Erlang, você não tem acesso aos threads do SO subjacente apenas aos processos leves que a VM do Erlang fornece.
10

Recebo algumas perguntas sobre multithreading durante entrevistas ...

Bem, para passar nas entrevistas, o multithreading pode ser bastante importante. Citando a si mesmo , "ao entrevistar candidatos para nossa equipe, faço perguntas de concorrência não porque essas habilidades são importantes em nosso projeto ( não são ), mas porque, de alguma forma, facilitam a avaliação do conhecimento geral da linguagem que usamos ..."

mosquito
fonte
2
Ter alguma idéia sobre programação multithreading e simultânea também geralmente se traduz em uma abordagem defensiva, o que pode ser uma coisa muito boa. Se você precisar levar em conta que algo totalmente não relacionado em seu processo pode ou não antecipar uma única declaração lógica e executar no meio de tudo o mais, é necessário planejar essa possibilidade. As implementações multithread (ao contrário de outras formas de simultaneidade) simplesmente significam que você tem a carga adicional de que isso pode fazer algo com qualquer estado que não seja local de encadeamento.
um CVn
6

Entender como alavancar o encadeamento para melhorar o desempenho é uma habilidade essencial no ambiente de software atual, para a maioria dos setores e aplicativos.

No mínimo, entender os problemas envolvidos com a simultaneidade deve ser um dado.

A observação óbvia de que nem todos os aplicativos ou ambientes poderão tirar proveito disso se aplica, por exemplo, em muitos sistemas embarcados. No entanto, parece que o processador Atom (et al) parece estar trabalhando para mudar isso (multicore leve começando a se tornar mais comum).

Stephen
fonte
4

Parece que você já está escrevendo código multithread.

A maioria dos aplicativos da web Java pode manipular várias solicitações ao mesmo tempo e faz isso usando vários encadeamentos.

Portanto, eu diria que é importante conhecer pelo menos o básico.

Tom Jefferys
fonte
18
<nitpick> aparentemente (s) que ele não está escrevendo código multithreaded, somente o código (single threaded), que é executado em um ambiente multithread </ nitpick>.
Péter Török
2

Ainda é importante em situações em que você precisa, mas, como muitas coisas no desenvolvimento, é a ferramenta certa para o trabalho certo. Passei três anos sem tocar na segmentação, agora praticamente tudo o que faço tem alguns fundamentos. Com os processadores com vários núcleos, ainda existe uma grande necessidade de segmentação, mas todos os motivos tradicionais ainda são válidos, você ainda deseja interfaces responsivas e deseja lidar com a sincronização e continuar com outras coisas ao mesmo tempo.

Nicholas Smith
fonte
2

Resposta curta: Muito.

Resposta mais longa: Os computadores eletrônicos (baseados em transistor) estão se aproximando rapidamente dos limites físicos da tecnologia. Está ficando cada vez mais difícil extrair mais relógios de cada núcleo enquanto gerencia a geração de calor e os efeitos quânticos dos circuitos microscópicos (os caminhos dos circuitos já estão sendo colocados tão próximos entre os chips modernos que um efeito chamado "tunelamento quântico" pode produzir um elétron "pular os trilhos" de um circuito para outro, sem precisar das condições adequadas para um arco elétrico tradicional); portanto, praticamente todos os fabricantes de chips estão focados em tornar cada relógio capaz de fazer mais, colocando mais "unidades de execução" em cada CPU. Então, em vez de o computador fazer apenas uma coisa por relógio, ele pode fazer 2, 4 ou até 8. A Intel possui "HyperThreading", que basicamente divide um núcleo da CPU em dois processadores lógicos (com algumas limitações). Praticamente todos os fabricantes estão colocando pelo menos dois núcleos de CPU separados em um chip de CPU, e o atual padrão ouro para CPUs de desktop é de quatro núcleos por chip. Oito é possível quando dois chips de CPU são usados, há placas-mãe de servidor projetadas para processadores "quad quad-core" (16 EUs mais HT opcional), e é provável que a próxima geração de CPUs tenha seis ou oito por chip.

O resultado disso é que, para tirar o máximo proveito da maneira como os computadores estão ganhando poder de computação, você deve permitir que o computador "divida e conquiste" seu programa. Os idiomas gerenciados possuem pelo menos um encadeamento de GC que lida com o gerenciamento de memória separadamente do seu programa. Alguns também possuem threads de "transição" que manipulam a interoperabilidade COM / OLE (tanto para proteger a "caixa de areia" gerenciada quanto para o desempenho). Além disso, você realmente precisa começar a pensar em como seu programa pode fazer várias coisas simultaneamente e arquitetar seu programa com recursos projetados para permitir que partes do programa sejam manipuladas de forma assíncrona. O Windows e os usuários do Windows praticamente esperam que seu programa execute tarefas longas e complicadas em threads de segundo plano, que mantém a interface do usuário do seu programa (que é executada no thread principal do programa) "responsiva" ao loop de mensagens do Windows. Obviamente, problemas que têm soluções paralelizáveis ​​(como classificação) são candidatos naturais, mas há um número finito de tipos de problemas que se beneficiam da paralelização.

KeithS
fonte
1

Apenas um aviso sobre multithreading: mais threads não significam melhor eficiência. Se não forem gerenciados corretamente, eles podem tornar o sistema mais lento. O ator da Scala aprimora o encadeamento do Java e maximiza o uso do sistema (mencionado como você é um desenvolvedor Java).

EDIT: Aqui estão algumas coisas que você deve ter em mente sobre as desvantagens do multithreading:

  • interferência de encadeamentos entre si ao compartilhar recursos de hardware
  • Os tempos de execução de um único encadeamento não são aprimorados, mas podem ser degradados, mesmo quando apenas um encadeamento está em execução. Isso ocorre devido a frequências mais lentas e / ou estágios adicionais do pipeline que são necessários para acomodar o hardware de comutação de threads.
  • O suporte de hardware para multithreading é mais visível para o software, exigindo, portanto, mais alterações nos programas aplicativos e sistemas operacionais do que o Multiprocessamento.
  • Dificuldade de gerenciar simultaneidade.
  • Dificuldade de testar.

Além disso, esse link pode ser de alguma ajuda sobre o mesmo.

c0da
fonte
2
Isso não parece responder à pergunta do OP: - /
Péter Török
No entanto, ele fornece uma visão de nível superior (mais) do encadeamento. Uma coisa a considerar antes de se aprofundar no multi-threading.
C0da
@ c0da Stack Exchange não é um painel de discussão: as respostas devem responder diretamente à pergunta. Você pode expandir sua resposta para retornar ao que o solicitante está procurando?
1

Isso me deixou imaginando a importância do Multithreading no cenário atual do setor.

Em campos críticos de desempenho, nos quais o desempenho não é proveniente de códigos de terceiros que realizam trabalhos pesados, mas sim os nossos, então eu tenderia a considerar as coisas nesta ordem de importância da perspectiva da CPU (GPU é um curinga que ganhei entrar):

  1. Eficiência de memória (ex: localidade de referência).
  2. Algorítmico
  3. Multithreading
  4. SIMD
  5. Outras otimizações (dicas de previsão de ramificação estática, por exemplo)

Observe que esta lista não se baseia apenas na importância, mas em muitas outras dinâmicas, como o impacto que elas causam na manutenção, o quanto elas são diretas (se não, vale a pena considerar com mais antecedência), suas interações com outras pessoas da lista etc.

Eficiência de memória

A maioria pode se surpreender com a minha escolha de eficiência de memória em vez de algorítmica. Isso ocorre porque a eficiência da memória interage com todos os outros 4 itens desta lista, e é porque a consideração está frequentemente na categoria "design" e não na categoria "implementação". É certo que existe um problema de galinha ou ovo aqui, pois entender a eficiência da memória geralmente requer considerar todos os 4 itens da lista, enquanto todos os outros 4 itens também exigem considerar a eficiência da memória. No entanto, está no coração de tudo.

Por exemplo, se precisarmos de uma estrutura de dados que ofereça acesso seqüencial em tempo linear e inserções em tempo constante na parte traseira e nada mais para pequenos elementos, a ingênua opção aqui a ser alcançada seria uma lista vinculada. Isso desconsidera a eficiência da memória. Quando consideramos a eficiência da memória no mix, acabamos escolhendo estruturas mais contíguas nesse cenário, como estruturas baseadas em matrizes crescíveis ou nós mais contíguos (por exemplo: um que armazena 128 elementos em um nó) vinculados ou, no mínimo, uma lista vinculada apoiada por um alocador de pool. Eles têm uma vantagem dramática, apesar de terem a mesma complexidade algorítmica. Da mesma forma, geralmente escolhemos a classificação rápida de uma matriz e a classificação de mesclagem, apesar de uma complexidade algorítmica inferior, simplesmente devido à eficiência da memória.

Da mesma forma, não podemos ter multithreading eficiente se nossos padrões de acesso à memória são tão granulares e dispersos por natureza que acabamos maximizando a quantidade de compartilhamento falso enquanto bloqueamos nos níveis mais granulares do código. Portanto, a eficiência da memória multiplica a multithreading de eficiência. É um pré-requisito para aproveitar ao máximo os threads.

Cada item acima na lista tem uma interação complexa com os dados, e o foco na forma como os dados são representados é, em última análise, o objetivo da eficiência da memória. Cada um dos itens acima pode ter gargalos com uma maneira inadequada de representar ou acessar dados.

Outra eficiência da memória razão é tão importante é que ele pode aplicar em toda a toda a base de código. Geralmente, quando as pessoas imaginam que as ineficiências se acumulam a partir de pequenas seções de trabalho aqui e ali, é um sinal de que elas precisam pegar um criador de perfil. No entanto, os campos de baixa latência ou aqueles que lidam com hardware muito limitado encontrarão, mesmo após a criação de perfil, sessões que não indicam pontos de acesso claros (apenas algumas vezes dispersas por todo o lugar) em uma base de código que é flagrantemente ineficiente na maneira como aloca, copia e acessando a memória. Normalmente, essa é a única vez que uma base de código inteira pode ser suscetível a uma preocupação de desempenho que pode levar a um novo conjunto de padrões aplicados em toda a base de código, e a eficiência da memória geralmente está no centro dela.

Algorítmico

Esse é praticamente um dado, pois a escolha em um algoritmo de classificação pode fazer a diferença entre uma entrada massiva que leva meses para classificar versus segundos para classificar. Causa o maior impacto de todos, se a escolha for entre, digamos, algoritmos quadráticos ou cúbicos realmente abaixo do par e um linearitmico, ou entre linear e logarítmico ou constante, pelo menos até termos mais de 1.000.000 de máquinas principais (nesse caso, memória eficiência se tornaria ainda mais importante).

No entanto, ele não está no topo da minha lista pessoal, já que alguém competente em seu campo saberia usar uma estrutura de aceleração para a seleção de frustum, por exemplo, estamos saturados de conhecimento algorítmico e saber coisas como usar uma variante de um trie como uma árvore de raiz para pesquisas baseadas em prefixos é coisa de bebê. Na falta desse tipo de conhecimento básico do campo em que estamos trabalhando, a eficiência algorítmica certamente chegaria ao topo, mas muitas vezes a eficiência algorítmica é trivial.

Também inventar novos algoritmos pode ser uma necessidade em alguns campos (por exemplo: no processamento de malha, tive que inventar centenas, pois eles não existiam antes ou as implementações de recursos semelhantes em outros produtos eram segredos de propriedade, não publicados em um artigo ) No entanto, uma vez que passamos pela parte da solução de problemas e encontramos uma maneira de obter os resultados corretos, e uma vez que a eficiência se torna o objetivo, a única maneira de realmente obtê-la é considerar como estamos interagindo com os dados (memória). Sem entender a eficiência da memória, o novo algoritmo pode se tornar desnecessariamente complexo com esforços fúteis para torná-lo mais rápido, quando a única coisa necessária era uma consideração um pouco mais da eficiência da memória para gerar um algoritmo mais simples e elegante.

Por fim, os algoritmos tendem a estar mais na categoria "implementação" do que na eficiência da memória. Em geral, é mais fácil melhorar em retrospectiva, mesmo com um algoritmo abaixo do ideal usado inicialmente. Por exemplo, um algoritmo inferior de processamento de imagem geralmente é implementado em um local local na base de código. Pode ser trocado por um melhor mais tarde. No entanto, se todos os algoritmos de processamento de imagem estiverem vinculados a uma Pixelinterface que tenha uma representação de memória abaixo do ideal, mas a única maneira de corrigi-lo é alterar a maneira como vários pixels são representados (e não um único), então geralmente SOL e terá que reescrever completamente a base de código para umImageinterface. O mesmo tipo de coisa vale para substituir um algoritmo de classificação - geralmente é um detalhe de implementação, enquanto uma alteração completa na representação subjacente dos dados que estão sendo classificados ou na maneira como eles passam pelas mensagens pode exigir que as interfaces sejam redesenhadas.

Multithreading

O multithreading é difícil no contexto do desempenho, pois é uma otimização em nível micro que atende às características do hardware, mas nosso hardware está realmente escalando nessa direção. Já tenho colegas que têm 32 núcleos (só tenho 4).

No entanto, o multithreading está entre as micro-otimizações mais perigosas, provavelmente conhecidas por um profissional, se o objetivo for usado para acelerar o software. A condição de corrida é praticamente o bug mais mortal possível, pois é de natureza tão indeterminista (talvez apenas aparecendo uma vez a cada poucos meses na máquina de um desenvolvedor no momento mais inconveniente fora do contexto de depuração, se houver). Portanto, tem sem dúvida a degradação mais negativa na capacidade de manutenção e potencial correção de código entre todas elas, especialmente porque os erros relacionados ao multithreading podem facilmente voar sob o radar, mesmo nos testes mais cuidadosos.

No entanto, está se tornando tão importante. Embora nem sempre possa superar algo como a eficiência da memória (que às vezes pode tornar as coisas cem vezes mais rápidas), dado o número de núcleos que temos agora, estamos vendo cada vez mais núcleos. É claro que, mesmo em máquinas com 100 núcleos, eu ainda colocaria a eficiência da memória no topo da lista, pois a eficiência do encadeamento é geralmente impossível sem ela. Um programa pode usar uma centena de threads em uma máquina assim e ainda ser lento, sem representação eficiente da memória e padrões de acesso (que se vincularão aos padrões de bloqueio).

SIMD

O SIMD também é um pouco estranho, pois os registros estão realmente ficando mais amplos, com planos de se tornar ainda mais amplos. Originalmente, vimos registros MMX de 64 bits seguidos por registros XMM de 128 bits, capazes de realizar 4 operações SPFP em paralelo. Agora estamos vendo registros YMM de 256 bits com capacidade para 8 em paralelo. E já existem planos para registros de 512 bits que permitiriam 16 em paralelo.

Eles interagem e se multiplicam com a eficiência do multithreading. No entanto, o SIMD pode degradar a capacidade de manutenção tanto quanto o multithreading. Embora os bugs relacionados a eles não sejam necessariamente tão difíceis de reproduzir e corrigir como uma condição de impasse ou corrida, a portabilidade é incômoda e garantir que o código possa ser executado na máquina de todos (e usar as instruções apropriadas com base em seus recursos de hardware) é estranho.

Outra coisa é que, embora os compiladores hoje em dia geralmente não batam o código SIMD escrito por especialistas, eles vencem tentativas ingênuas facilmente. Eles podem melhorar até o ponto em que não precisamos mais fazê-lo manualmente, ou pelo menos sem sermos tão manuais a ponto de escrever códigos intrínsecos ou de montagem direta (talvez apenas um pouco de orientação humana).

Novamente, porém, sem um layout de memória eficiente para o processamento vetorizado, o SIMD é inútil. Acabaremos apenas carregando um campo escalar em um registro amplo apenas para fazer uma operação nele. No centro de todos esses itens, há uma dependência dos layouts de memória para ser realmente eficiente.

Outras otimizações

Isso é frequentemente o que eu sugeriria que começássemos a chamar de "micro" hoje em dia se a palavra sugerir não apenas ir além do foco algorítmico, mas também em direção a mudanças que tenham um impacto minúsculo no desempenho.

Muitas vezes, tentar otimizar a previsão de ramificação requer uma alteração na eficiência do algoritmo ou da memória, por exemplo, se isso for tentado apenas através de dicas e reorganização do código para previsão estática, isso só tende a melhorar a execução inicial desse código, tornando os efeitos questionáveis ​​se nem sempre é insignificante.

Voltar para Multithreading for Performance

Enfim, qual a importância da multithreading de um contexto de desempenho? Na minha máquina de 4 núcleos, o ideal é tornar as coisas cerca de 5 vezes mais rápidas (o que posso obter com o hyperthreading). Seria consideravelmente mais importante para o meu colega que tem 32 núcleos. E isso se tornará cada vez mais importante nos próximos anos.

Então é muito importante. Mas é inútil apenas lançar um monte de threads no problema se a eficiência da memória não existir para permitir que os bloqueios sejam usados ​​com moderação, para reduzir o compartilhamento falso etc.

Multithreading fora do desempenho

Multithreading nem sempre é sobre puro desempenho, em um sentido direto da taxa de transferência. Às vezes, é usado para equilibrar uma carga, mesmo com o custo possível da taxa de transferência, para melhorar a capacidade de resposta ao usuário ou permitir que o usuário faça mais multitarefas sem esperar que as coisas terminem (por exemplo: continue navegando enquanto faz o download de um arquivo).

Nesses casos, eu sugiro que o multithreading suba ainda mais para o topo (possivelmente até acima da eficiência da memória), já que trata-se de design do usuário final, e não de tirar o máximo proveito do hardware. Muitas vezes, ele domina os designs de interface e a maneira como estruturamos toda a nossa base de código em tais cenários.

Quando não estamos simplesmente paralelizando um loop restrito acessando uma estrutura de dados massiva, o multithreading vai para a categoria "design" realmente incondicional, e o design sempre supera a implementação.

Portanto, nesses casos, eu diria que considerar o multithreading inicial é absolutamente crítico, ainda mais do que a representação e o acesso à memória.


fonte
0

Programação simultânea e paralela é o que está se tornando importante. Threads são apenas um modelo de programação para fazer várias coisas ao mesmo tempo (e não em pseudo-paralelo como costumava ser antes do surgimento de processadores com vários núcleos). O multithread é (IMHO razoavelmente) criticado por ser complexo e perigoso, pois os threads compartilham muitos recursos e o programador é responsável por fazê-los cooperar. Caso contrário, você acaba com conflitos que são difíceis de depurar.

sakisk
fonte
0

Como podemos precisar entrar em contato com muitos aplicativos externos, pode haver algum processo em segundo plano onde a interação do sistema externo leva mais tempo e o usuário final não pode esperar até que o processo seja concluído. então Multithreading é importante ..

como estamos usando em nosso aplicativo, primeiro tentamos entrar em contato com o sistema externo, se estiver inoperante, em seguida, salvamos a solicitação no banco de dados e expandimos um segmento para concluir o processo em backgound. Pode ser necessário também nas operações em lote.

TPReddy
fonte
0

Historicamente, as pessoas tinham que lutar fazendo programação multithread manualmente. Eles tiveram que trabalhar com todos os componentes principais (threads, semáforos, mutexes, bloqueios, etc.) diretamente.

Todos esses esforços resultaram em aplicativos capazes de escalar adicionando cpus adicionais a um único sistema. Essa escalabilidade vertical é limitada pelo "qual é o maior servidor que posso comprar".

Atualmente vejo uma mudança no uso de mais estruturas e modelos de design diferentes para o design de software. O MapReduce é um desses modelos, focado no processamento em lote.

O objetivo é escalar horizontalmente. Adicionando mais servidores padrão em vez de comprar servidores maiores.

Dito isto, permanece o fato de que realmente entender a programação multithread é muito importante. Eu estive na situação em que alguém criou uma condição de corrida e nem sabia o que é uma condição de corrida até que notamos erros estranhos durante o teste.

Niels Basjes
fonte
-1

Minha máquina possui 8 núcleos. No Gerenciador de tarefas, tenho 60 processos em execução. Alguns, como o VS, usam até 98 threads. O Outlook usa 26. Espero que a maior parte do meu uso de memória seja as pilhas alocadas a cada um desses threads ociosos.

Pessoalmente, estou aguardando a saída do computador de 300 núcleos para não precisar esperar que o Outlook responda. É claro que até então o Outlook usará 301 threads.

A multithreading só importa se você estiver construindo sistemas que serão o único processo importante no computador em um determinado momento (por exemplo, mecanismos de cálculo). Os aplicativos de desktop provavelmente fariam um favor ao usuário por não usar todos os núcleos disponíveis. Os aplicativos da Web que usam o modelo de solicitação / resposta são inerentemente multiencadeados.

É importante para designers de estrutura e linguagem e programadores de sistemas de back-end - não muito para os construtores de aplicativos. Provavelmente vale a pena entender alguns conceitos básicos, como bloquear e escrever código assíncrono.

Paul Stovell
fonte
Vou muitas vezes bater algo em um segmento de segundo plano, como uma carga DB longa, mas é muito raro que eu tenho que lidar com as condições de corrida ou bloqueios etc. (na verdade provavelmente nunca)
Aran Mulholland