Funzioni inline in C++

Jinku Hu 12 ottobre 2023
Funzioni inline in C++

Questo articolo spiegherà come incorporare una funzione in C++.

Il concetto di funzione Inlining

Le funzioni sono la pietra angolare di molti linguaggi di programmazione. Si presume che le caratteristiche comuni delle funzioni siano note al lettore di questo articolo, quindi ci concentreremo sui dettagli dell’esecuzione delle funzioni dal punto di vista delle prestazioni della CPU e motiveremo la necessità di incorporare le funzioni.

In questo caso, supponiamo di eseguire il nostro programma su un singolo core della CPU. In genere, una CPU recupera le istruzioni dalla memoria e le esegue in ordine. Si noti che la chiamata a una funzione costringe la CPU a passare a un diverso indirizzo non sequenziale, il che risulta essere costoso. Inoltre, alcune strutture devono essere impostate durante la chiamata di funzione, come uno stack frame. L’ambiente di esecuzione dovrebbe salvare e ripristinare i registri di ciascuna funzione e vengono eseguite alcune altre operazioni varie, che influiscono tutte sulle prestazioni del programma. Di conseguenza, è preferibile eliminare le chiamate di funzione non necessarie.

La riduzione del tempo speso per le chiamate di funzione può essere eseguita su diversi livelli di programma; ad esempio, il compilatore può tentare di ottimizzare il codice macchina generato per eliminare chiamate di funzioni non necessarie o il sistema operativo per implementare tecniche di chiamata rapida. Il programmatore potrebbe avere alcune informazioni uniche sul programma che potrebbero aiutare a ottimizzare le chiamate di funzione.

Quest’ultimo viene solitamente eseguito riducendo manualmente il numero delle chiamate di funzione o contrassegnando la funzione come inline. La parola chiave inline indica al compilatore che deve generare il codice macchina in modo che venga saltato il normale meccanismo di chiamata della funzione. Alcuni compilatori di solito eseguono quest’ultima ottimizzazione, oppure alcuni potrebbero aver bisogno di determinati flag per indicare che l’ottimizzazione è necessaria. È importante ricordare che la parola chiave inline viene trattata come un suggerimento e non come una garanzia dal compilatore. Tuttavia, il programmatore potrebbe preferire contrassegnare le funzioni quando possibile per raggiungere prestazioni ottimali.

La buona regola pratica è che vale la pena inserire la funzione in linea se è relativamente piccola e viene chiamata in un’unica posizione. La funzione può essere inline specificando la parola chiave inline all’inizio della sua definizione. L’esempio seguente mostra due funzioni inline denominate doubleInt e convolutionInt. Una volta che il compilatore ha effettivamente inlineato la funzione, la sua sequenza di codice viene inserita nel corpo delle funzioni chiamanti, in modo simile alle espressioni macro quando sostituiscono la sequenza di stringhe data con lo snippet corrispondente.

#include <iostream>

inline int doubleInt(int a) { return a + a; }

inline int convolutionInt(int a, int b) { return doubleInt(a) * b; }

int main() {
  int k = 10;

  std::cout << doubleInt(k) << std::endl;

  k = convolutionInt(k, k + 5);
  std::cout << k << std::endl;

  return EXIT_SUCCESS;
}

In conclusione, non si dovrebbe trattare la funzione inline come il metodo garantito per generare migliori prestazioni dai programmi. Più a quest’ultimo punto, è piuttosto difficile valutare i compromessi delle prestazioni delle funzioni in linea poiché i sistemi contemporanei utilizzano vari meccanismi per eseguire il codice più velocemente. Ciascuno di questi meccanismi può essere influenzato contrassegnando prematuramente le funzioni come inline.

Questo ci porta alla trappola comune dell’ottimizzazione del software come problema generale. È considerata una cattiva pratica cercare di ottimizzare ogni singola parte del programma in anticipo. È meglio profilare il programma per capire le parti più complesse e concentrare lo sforzo di ottimizzazione su quelle.

Autore: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Articolo correlato - C++ Function