Sì e no. Dipende dai vincoli che desideri soddisfare e dalle precondizioni necessarie per eseguire l'algoritmo.
Idealmente, un algoritmo è una ricetta astratta che definisce passo-passo come fare qualcosa. Gli algoritmi sono stati definiti in questo modo con l'obiettivo di riproducibilità e in seguito di automatizzazione. Gli algoritmi provengono da lambda-calcul, quindi puoi facilmente capire perché sono fatti in questo modo. Questa definizione è la solita, ma gli algoritmi moderni possono essere non sequenziali (non graduali, come algoritmi concorrenti, o logici come quelli che usano l'unificazione), non lineari (algoritmi stocastici) o semplicemente chiaramente (quantum algoritmi), ma lo passerò.
Quindi, idealmente, un algoritmo dovrebbe essere il più astratto possibile senza contare l'hardware.
Tuttavia, come con qualsiasi sistema, devi definire alcuni assiomi , non solo per ottenere un sistema coerente, ma anche per guadagnare tempo. Ad esempio, la maggior parte degli algoritmi presume, perlomeno implicitamente, che siano definiti su una macchina Von-Neumann. Se così non fosse, avrebbero bisogno di definire in modo esplicito ogni parte del sistema di cui hanno bisogno per essere eseguiti (poiché questo è necessario per riprodurre la ricetta, questa è una sorta di precondizione). Inoltre, spesso gli algoritmi si basano su comandi comuni come write () senza definirli completamente.
Un altro motivo per cui gli algoritmi non sono così astratti dall'architettura hardware, è quando devi soddisfare alcuni vincoli .
Diciamo che stai lavorando su sistemi embedded, quindi probabilmente non puoi contare sulla stessa quantità di risorse che hai sulle workstation. Una delle risorse più contenute è probabilmente la memoria. Tuttavia, la maggior parte degli algoritmi tende a ottimizzare la complessità del tempo (velocità di esecuzione sulla CPU), non la complessità della memoria (quantità di memoria necessaria per lavorare sui dati). Per questi sistemi, sono stati ideati algoritmi di memoria ottimizzati in cui gli algoritmi non ottimizzati per la memoria fallirebbero o sarebbero molto più lenti. In effetti, i sistemi embedded non sono l'unico obiettivo di algoritmi efficienti per la memoria: ad esempio, ci sono algoritmi cache-oblivious che adatta la loro elaborazione per utilizzare in modo efficiente la cache della CPU. Un altro esempio: alcuni algoritmi di apprendimento automatico per i big data sono adattati per apprendimento incrementale o calcolo fuori dai core per elaborare enormi quantità di dati molto più grandi della memoria disponibile su qualsiasi computer, ecc.
Esistono anche algoritmi che non ottimizzano una parte specifica del computer, ma uno standard che dipende dall'architettura hardware. Ad esempio, i dati numerici che richiedono precisione sono memorizzati all'interno di float o double, che sono per natura limitati a causa dei limiti hardware. Il problema è che calcoli complessi possono portare all'arrotondamento e più calcoli esegui su numeri arrotondati, più ti lascerai alla larga. Questa è chiamata interferenza catastrofica . Alcune applicazioni richiedono una precisione critica, anche a scapito della peggiore complessità. Per questo tipo di applicazioni, sono stati apportati algoritmi che ottimizzano il calcolo per ridurre o rimuovere le interferenze catastrofiche.
Quindi, progettare un algoritmo può anche essere un compromesso tra astrazione e vincoli.
Alla fine, possiamo dire che un algoritmo è astratto quanto il suo obiettivo, e come il suo precondizionato (architettura) ha bisogno di . Il target più specifico che il tuo algoritmo mira, più probabilmente si baserà sull'architettura hardware.
Alcune parole chiave correlate che potrebbero interessarti: