W jaki sposób instrukcje Thumb różnią się od instrukcji ARM dotyczących wydajności?

11

Kolega wspomniał, że instrukcje Thumb były znacznie wolniejsze niż instrukcje ARM (dotyczyło to procesora AT91SAM7S32). Czy to prawda? Jakie są zalety wydajności jednego zestawu instrukcji względem drugiego?

Patrick
źródło

Odpowiedzi:

11

Ogólnie

Według mnie instrukcje THUMB nie są wewnętrznie wolniejsze niż instrukcje ARM, ale mają bardziej ograniczone możliwości. Jeśli twój kod potrzebuje tylko funkcjonalności instrukcji THUMB, zajmie mniej miejsca niż ARM, ale będzie miał taką samą liczbę instrukcji i, przy innych rzeczach równych, będzie działał z tą samą prędkością. Jeśli twój kod wymaga większej funkcjonalności, niż wymagałoby wykonania większej liczby instrukcji THUMB niż instrukcji ARM i zająłoby to więcej czasu, znowu inne rzeczy byłyby takie same (patrz poniżej)

THUMB jest popularny w mikrokontrolerach ze względu na mniejszy rozmiar instrukcji z dwóch powodów:

  1. Przestrzeń programu jest często ograniczona
  2. Wiele mikrokontrolerów ma 16-bitowe szyny danych do wewnętrznej pamięci flash

Z drugiego powodu, gdy twój kod nie wymaga funkcjonalności z zestawu instrukcji ARM, kod THUMB faktycznie działa szybciej. Wynika to z faktu, że twoja instrukcja może być pobierana w jednym cyklu I / O z pamięci flash zamiast dwóch. W zależności od szybkości interfejsu flash ten drugi odczyt może spowodować jeden lub więcej cykli oczekiwania na instrukcję, w których procesor po prostu utknął w martwym punkcie i nie może nic zrobić.

Staje się to mniejszym problemem, jeśli możesz skopiować kod do pamięci RAM przed uruchomieniem (co zwykle widziałem jako 32-bitowe w przypadku najnowszych mikrokontrolerów ARM), gdzie jedynym problemem jest gęstość kodu. W tym celu wiele narzędzi spróbuje znaleźć, która reprezentacja jest bardziej wydajna dla danej funkcji. Jeśli kompilator może wygenerować kod THUMB w mniejszej liczbie instrukcji, zrobi to, ale jeśli ARM spowoduje mniej instrukcji, otrzymasz ARM. Jest to domyślny tryb dla Keila, jeśli dobrze pamiętam.

Twój konkretny układ

W przypadku konkretnego układu (AT91SAM7S32) w dokumentacji wspomniano, że kontroler flash ma bufor pobierania wstępnego, który może przewidywać dostęp w celu zwiększenia wydajności, co może usprawnić wykonywanie instrukcji ARM. Wskazuje jednak również, że pobieranie wstępne jest „podwójnym 32-bitowym” buforem, który „optymalizuje 16-bitowy dostęp”, co jest najbardziej odpowiednie do „działania w trybie Thumb”, co wydaje się wskazywać, że nie jest przeznaczone do przyspieszenia Instrukcje ARM, ale aby rdzeń mógł działać szybciej w trybie THUMB.

Ze schematów wygląda na to, że flash na twoim chipie faktycznie ma 32-bitową szynę danych. Preselektor wydaje się działać, czytając całe 32 bity, przekazując 16 procesorowi (w trybie THUMB) i buforując całe 32 bity. Podczas następnego cyklu, gdy procesor odczytuje drugie 16 bitów, tym razem z pamięci podręcznej, kontroler pamięci flash odczytuje kolejne 32 bity i buforuje je. W ten sposób kod THUMB może działać bez początkowego oczekiwania, nawet jeśli szybkość flashowania byłaby nieco mniejsza niż prędkość rdzenia procesora. Sekcja 19.2.2 „Operacje odczytu” zawiera więcej szczegółów.

Ponieważ twoja pamięć flash jest 32-bitową magistralą (tak blisko, jak mogę to stwierdzić), jeśli twój procesor i zegary Flash są takie same, THUMB da ci gęstość kodu tylko w stosunku do ARM. Jeśli chcesz, aby twój rdzeń procesora działał szybciej niż Flash (i zauważ, że nie sprawdziłem całego taktowania tego układu; zakładam, że procesor może działać szybciej, ponieważ pozwalają ci ustawić stany oczekiwania), to pobieranie wstępne daje prędkość zaletą dla THUMB ze względu na ograniczenie faktycznego dostępu do lampy błyskowej. Jednak ta przewaga prędkości jest zaletą dla instrukcji. Jeśli liczba instrukcji THUMB w porównaniu z instrukcjami ARM jest wystarczająco duża, przeważy ona szybkość na instrukcję, co spowoduje, że ARM będzie miał większą prędkość na procedurę.

John O'M.
źródło