Earth Engine korzysta z narzędzi i usług Google do przeprowadzania obliczeń na ogromną skalę. Aby ułatwić przeprowadzanie dużych analiz geoprzestrzennych, platforma i interfejs Earth Engine API ukrywają większość złożoności bazowej infrastruktury przetwarzania równoległego.
EECU
Przegląd
Jednostka obliczeniowa Earth Engine (EECU) to mechanizm reprezentujący ilość natychmiastowej mocy obliczeniowej. Earth Engine śledzi całkowity ślad obliczeniowy zadań jako funkcję ich wykorzystania EECU w czasie (sekundy EECU, godziny EECU itp.). Google ma wiele różnych typów rdzeni procesora, architektur itp. EECU to przydatna abstrakcja do mówienia o mocy obliczeniowej.
Motywacja
Użytkownicy EE często chcą oszacować moc obliczeniową wymaganą do realizacji swoich procesów, a EECU to spójny wskaźnik, który umożliwia porównywanie.
Porównanie z danymi dotyczącymi procesora
Liczba, typ i architektura maszyn pracujących nad konkretnym wynikiem mogą się z czasem zmieniać. Różne rdzenie fizyczne mogą mieć różne charakterystyki wydajności, dlatego Earth Engine abstrahuje wszystkie procesy za pomocą jednostek EECU. Godzina EECU (lub dowolna inna jednostka czasu EECU) nie odpowiada czasowi zegarowemu, więc zadanie, które zużywa 10 godzin EECU, może mieć zaobserwowany czas działania wynoszący zaledwie kilka minut.
Stabilność i przewidywalność
Wysyłanie do Earth Engine tych samych (lub podobnych) żądań może czasami skutkować bardzo różnymi ilościami obliczeń. Częste przyczyny różnic:
- buforowanie, np. ponowne wykorzystywanie wyników poprzednich obliczeń (w tym wyników częściowych lub pośrednich);
- różne dane podstawowe, np. różna liczba zdjęć satelitarnych, geometrie o różnym stopniu złożoności itp.
- zmiany algorytmów na platformie EE, w tym optymalizacje wydajności, poprawki błędów itp.
- zmiany w bibliotekach klienta, zwłaszcza jeśli korzystasz z kodu lub pakietów EE innych użytkowników;
Testy porównawcze
Zapoznaj się z przykładowymi testami porównawczymi obliczeń w Earth Engine.
Dane o nieudanych żądaniach
Earth Engine nie podaje danych o skuteczności w przypadku nieudanych żądań lub zadań, ponieważ te liczby byłyby niedokładne lub wprowadzające w błąd. Jeśli na przykład zadanie zakończy się niepowodzeniem, ponieważ zadanie instancji roboczej przestało odpowiadać, zużycie zasobów przez tę instancję nie będzie wliczane do łącznego zużycia.
Narzędzie do profilowania
Program profilujący dostarcza informacji o czasie wykorzystania jednostki EECU i wykorzystaniu pamięci (w przypadku każdego algorytmu i zasobu) w wyniku obliczeń wykonywanych, gdy jest włączony. Każdy wiersz w danych wyjściowych profilera odpowiada algorytmowi, obliczeniom, wczytywaniu zasobów lub operacji dodatkowej, zgodnie z opisem w kolumnie „Opis”. Kolumny w profilerze to:
- Opis
- Tekstowy opis obliczeń, algorytmu, wczytywania zasobu lub operacji dodatkowej, które są profilowane.
- Liczba
- Wskaźnik proporcjonalny do liczby wywołań operacji opisanej w sekcji „Opis”.
- Zasoby obliczeniowe
- Wskaźnik czasu EECU zajętego przez operacje.
- Bieżąca pamięć
Ta kolumna pojawia się tylko wtedy, gdy wystąpił błąd, ponieważ skrypt
wykorzystywała za dużo pamięci. Pokazuje ilość pamięci używanej w dowolnym węźle obliczeniowym w momencie wystąpienia błędu.
- Szczytowa pamięć
Maksymalna ilość pamięci używana w dowolnym węźle obliczeniowym na potrzeby operacji.
Włączanie profilera
Edytor kodu
Użyj przycisku „Uruchom z profilerem” zgodnie z opisem w przewodniku po edytorze kodu.
Python
Aby włączyć profiler, dodaj do skryptu w Pythonie ten kod:
with ee.profilePrinting():
print(ee.Number(3.14).add(0.00159).getInfo())
Profil zostanie wydrukowany po zakończeniu kontekstu, niezależnie od tego, czy w jego obrębie wystąpił błąd.
Aby zapisać profil jako ciąg znaków, zapisz go w buforze ciągu znaków:
import io
out = io.StringIO()
with ee.profilePrinting(destination=out) as p:
print(ee.Number(3.14).add(0.00159).getInfo())
print('Output:')
print(out.getvalue())
Oto propozycja przekształcenia ciągu profilu w tabelę, aby ułatwić analizę w Colab i notatnikach Jupyter (pamiętaj, że to tylko jedna z metod, która może nie być odpowiednia we wszystkich przypadkach):
import re
import pandas as pd
lines = out.getvalue().split('\n')
column_names = re.split(r'\s{1,}', lines[0])
column_names = [name.strip() for name in column_names if name.strip()]
data = [
[element for element in re.split(r'\s{2,}', line) if element.strip()]
for line in lines[1:-1]
]
df = pd.DataFrame(data, columns=column_names)
display(df)