Bystre optymalizacje – Typ do indeksowania tablic

W założeniach standardu C typ int miał być natywną reprezentacją liczb całkowitych. Niestety za czasów królowania systemów 32-bitowych wiele programów i bibliotek zostało napisanych z założeniem, że jest to właśnie typ o dokładnie tej wielkości. Kiedy pojawiły się systemy 64-bitowe, w zdecydowanej większości przypadków pozostawiono ów typ na mniejszej wielkości.

Na największe różnice można natrafić w przypadku indeksowania tablic. Zasadniczo w tym celu zdefiniowano typ size_t, który ma odpowiedni dla danej architektury rozmiar. Niestety dość często w tym celu używany jest wspomniany int, który w przypadku architektur 64-bitowych jest zazwyczaj za mały, więc kompilator i procesor muszą go konwertować.

Aby sprawdzić ów narzut przygotowałem dwie pary funkcji (1, 2) i uruchomiłem je na dwóch różnych systemach (A, B).

uint_fast32_t my_iterate_1_size_t(uint_least16_t *a)
{
	size_t i, s;
	s = get_array_size();
	uint_fast32_t ret = 0;
	for (i = 0; i < s; i++) {
		ret += a[i] & 0xff;
	}
	return ret;
}

uint_fast32_t my_iterate_1_int(uint_least16_t *a)
{
	int i, s;
	s = get_array_size();
	uint_fast32_t ret = 0;
	for (i = 0; i < s; i++) {
		ret += a[i] & 0xff;
	}
	return ret;
}

uint_fast32_t my_iterate_2_size_t(uint_least16_t *a)
{
	size_t i, d, s;
	s = get_array_size();
	d = get_array_step();
	uint_fast32_t ret = 0;
	for (i = 0; i < s; i += d) {
		ret += a[i] & 0xff;
	}
	return ret;
}

uint_fast32_t my_iterate_2_int(uint_least16_t *a)
{
	int i, d, s;
	s = get_array_size();
	d = get_array_step();
	uint_fast32_t ret = 0;
	for (i = 0; i < s; i += d) {
		ret += a[i] & 0xff;
	}
	return ret;
}

Wykresy

Wykres przy optymalizacji -O1

Chart 1

Wykres przy optymalizacji -O2

Chart 2

Wykres przy optymalizacji -O3

Chart 3

Podsumowanie

W większości przypadków wychodzi na to, że nie ma specjalnie różnicy wydajności. W nielicznych pozostałych można jednak zaobserwować przewagę stosowania typu size_t, nawet ok. 30%, ale to są wyjątki. Spodziewałem się zdecydowanie większych różnic.

Z drugiej strony dedykowany typ do indeksowania tablic zwiększa czytelność kodu. Pozwala też na uniknięcie dziwnych błędów, kiedy bufory mają większy rozmiar, niż można zapisać w typie int. Nie widzę więc powodu, aby nie stosować tej konwencji.