Sim e não. Depende das restrições que você deseja atender e das condições prévias necessárias para executar seu algoritmo.
Idealmente, um algoritmo é uma receita abstrata que define passo a passo como fazer algo. Os algoritmos foram definidos assim com o objetivo de reprodutibilidade e posterior automatização. Os algoritmos são originários do lambda-calcul, para que você possa ver facilmente por que eles são criados dessa maneira. Essa definição é a usual, mas os algoritmos modernos podem ser não seqüenciais (não passo a passo, como algoritmos simultâneos ou lógicos como os que usam unificação), não lineares (algoritmos estocásticos) ou simplesmente estranhos (quantum algoritmos), mas eu passo isso.
Assim, idealmente, um algoritmo deve ser o mais abstrato possível sem contabilizar nenhum hardware.
Mas, como em qualquer sistema, você deve definir alguns axiomas , não apenas para obter um sistema coerente, mas também para ganhar tempo. Por exemplo, a maioria dos algoritmos presume, pelo menos implicitamente, que eles são definidos em uma máquina de Von-Neumann. Se não fosse esse o caso, eles precisariam definir explicitamente cada parte do sistema em que precisam ser executados (já que isso é necessário para reproduzir a receita, é um tipo de pré-condição). Além disso, frequentemente os algoritmos dependem de comandos comuns, como write (), sem defini-los completamente.
Outra razão pela qual os algoritmos não são tão abstratos da arquitetura de hardware é quando você precisa atender a algumas restrições .
Digamos que você esteja trabalhando em sistemas embarcados, provavelmente não poderá contar com a mesma quantidade de recursos que possui nas estações de trabalho. Um dos recursos mais restritos é provavelmente a memória. No entanto, a maioria dos algoritmos tende a otimizar a complexidade do tempo (velocidade de execução na CPU), não a complexidade da memória (quantidade de memória necessária para trabalhar nos dados). Para esses sistemas, foram criados algoritmos de memória otimizada, onde algoritmos não otimizados para memória simplesmente falhariam ou seriam muito mais lentos. De fato, os sistemas embarcados não são o único alvo dos algoritmos com eficiência de memória: por exemplo, existem algoritmos que ignoram o cache que adaptam seu processamento para usar com eficiência o cache da CPU. Outro exemplo: alguns algoritmos de aprendizado de máquina para big data são adaptados paraaprendizado incremental ou computação fora do núcleo para processar uma quantidade enorme de dados muito maior que a memória disponível em qualquer computador, etc.
Também existem algoritmos que não otimizam uma parte específica do computador, mas um padrão que depende da arquitetura do hardware. Por exemplo, dados numéricos que precisam de precisão são armazenados dentro de float ou double, que são limitados por natureza devido a limites de hardware. O problema é que cálculos complexos podem levar a arredondamentos, e quanto mais cálculos você fizer sobre números arredondados, mais você se afastará. Isso é chamado de interferência catastrófica . Alguns aplicativos precisam de uma precisão crítica, mesmo ao custo da pior complexidade. Para esse tipo de aplicação, foram feitos algoritmos que otimizam seu cálculo para reduzir ou remover interferências catastróficas.
Assim, projetar um algoritmo também pode ser uma troca entre abstração e restrições.
No final, podemos dizer que um algoritmo é tão abstrato quanto seu alvo e como suas necessidades pré-condições (arquitetura) . Quanto mais específico o objetivo do seu algoritmo, mais provavelmente ele dependerá da arquitetura do hardware.
Algumas palavras-chave relacionadas que podem lhe interessar: