2009-10-28 15 views
18

Próbuję uruchomić następujący program, który oblicza pierwiastek wielomianów stopnia do d o współczynnikach tylko +1 lub -1, a następnie przechowuje go do plików.Mathematica zabrakło pamięci

d = 20; n = 18000; 
f[z_, i_] := Sum[(2 Mod[Floor[(i - 1)/2^k], 2] - 1) z^(d - k), {k, 0, d}]; 

Tutaj f [z, i] podaje wielomian w z z znakami plus lub minus liczącymi w systemie binarnym. Załóżmy, d = 2, to mamy

F [Ź, 1] = -Z - Z - 1
F [Z, 2] = -Z - Z + 1
F [ oo 3] = -Z + z - 1
f [z, 4] = -Z + z + 1

DistributeDefinitions[d, n, f] 

ParallelDo[ 
      Do[ 
        root = N[Root[f[z, i], j]]; 
        {a, b} = Round[n ({Re[root], Im[root]}/1.5 + 1)/2]; 
      {i, 1, 2^d}], 
{j, 1, d}] 

I uświadomić odczytu prawdopodobnie nie jest zbyt przyjemne , ale i tak jest względnie krótki. Próbowałbym ograniczyć się do odpowiednich części, ale tutaj naprawdę nie mam pojęcia, czym jest problem. Obliczam wszystkie korzenie f [z, i], a następnie zaokrąglaję je tak, aby odpowiadały punktowi w siatce n n, i zapisują te dane w różnych plikach.

Z jakiegoś powodu użycie pamięci w programie Mathematica jest skrępowane, dopóki nie zapełni całej pamięci (6 GB na tym komputerze); następnie obliczenia trwają bardzo powoli; dlaczego to?

Nie jestem pewien, co jest tutaj używane w pamięci - moim zdaniem tylko strumień plików zużył pamięć, ale tak nie jest: próbowałem dołączać dane do plików 2GB i nie było zauważalnego użycia pamięci dla tego . Wydaje się, że nie ma absolutnie żadnego powodu, aby Mathematica korzystała z dużej ilości pamięci.

Dla małych wartości d (15 na przykład), zachowanie jest następujące: Mam 4 jądra uruchomione. Gdy wszystkie przechodzą przez pętlę ParallelDo (każda z nich wykonuje wartość j jednocześnie), użycie pamięci wzrasta, aż wszyscy skończą przechodzić tę pętlę raz. Następnym razem, gdy przechodzą przez tę pętlę, użycie pamięci nie zwiększa się wcale. Obliczenia w końcu się kończą i wszystko jest w porządku.

Co więcej, po zakończeniu obliczeń zużycie pamięci nie spada. Jeśli zacznę kolejne obliczenia, następujące czynności:

-Jeśli poprzednie obliczenie zatrzymało się, gdy zużycie pamięci wciąż wzrastało, nadal rośnie (może to zająć trochę czasu, aby zacząć zwiększać ponownie, w zasadzie, aby dostać się do tego samego punktu w obliczeniach).

-Jeśli poprzednie obliczenia zostały zatrzymane, gdy zużycie pamięci nie wzrastało, nie zwiększa się ono dalej.

Edit: Problem wydaje się pochodzić od względnej złożoności F - zmieniając go do jakiegoś łatwiejszego wielomianu wydaje się rozwiązać problem. Pomyślałem, że problem może polegać na tym, że Mathematica zapamiętuje f [z, i] dla konkretnych wartości i, ale ustawia f [z, i]: =. tuż po obliczeniu pierwiastka z f [z, i] narzeka, że ​​zadanie nie istniało w pierwszej kolejności, a pamięć wciąż jest używana.

To naprawdę zagadkowe, ponieważ f jest jedyną pozostałą rzeczą, jaką mogę sobie wyobrazić, biorąc pod uwagę pamięć, ale definiowanie f w wewnętrznej pętli Do i czyszczenie jej za każdym razem po obliczeniu korzenia nie rozwiązuje problemu.

+0

Czy próbowałeś uruchomić ten algorytm z mniejszymi, a nawet pojedynczymi wartościami d? –

+0

Właśnie dodałem akapit opisujący, co dzieje się dla mniejszego d. –

+0

Co dzieje się po uruchomieniu programu bez otwierania strumienia, wykonywania zapisów i zamykania strumienia (tj. Bez żadnych operacji we/wy)? – Pillsy

Odpowiedz

11

Ouch, to jest paskudny.

Co to jest, że N zrobi buforowanie wyników w celu przyspieszenia przyszłych obliczeń, jeśli będzie to potrzebne ponownie. Czasem jest to absolutnie to, czego chcesz, ale czasami po prostu łamie świat. Na szczęście masz kilka opcji. Jedną z nich jest użycie polecenia ClearSystemCache, które robi dokładnie to, co napisano na puszce. Po krótkim uruchomieniu nierównoległej pętli (przed znudzeniem i przerwaniem obliczeń), MemoryInUse zgłosiło ~ 160 MB w użyciu. Korzystanie z ClearSystemCache obniżyło tę wartość do około 14 MB.

Jedną rzeczą, na którą powinieneś patrzeć, zamiast wywoływać programowo ClearSystemCache, jest użycie SetSystemOptions, aby zmienić zachowanie buforowania. Powinieneś rzucić okiem na SystemOptions["CacheOptions"], aby zobaczyć, jakie są możliwości.

EDYCJA: To nie jest dziwne, że buforowanie powoduje większy problem dla bardziej złożonych wyrażeń. Musi być gdzieś ukryte kopie tych wyrażeń, a bardziej złożone wyrażenia wymagają więcej pamięci.

+0

Hmm, mam problemy z replikowaniem twoich wyników. W chwili obecnej występują dwa problemy: w niezrównanej wersji, kiedy wywołuję ClearSystemCache, MemoryInUse zgłasza, że ​​używana pamięć cofnęła się, ale menedżer zadań pokazuje, że jądro wciąż zużywa tyle pamięci. Po drugie, w trybie równoległym nie mogę znaleźć opcji wyczyszczenia pamięci podręcznej poszczególnych jąder. Ale wydawało się, że znalazłeś dokładną przyczynę, teraz jest to bardziej kwestia znalezienia sposobu leczenia. –

+0

Wiadomości z CacheOptions również nie okazały się owocne - ustawiłem wszystko na false i maksymalne bajty na 0 i nie robiło to różnicy (do wersji niezrównanej i tak nie ma różnicy w wersji równoległej). –

+0

Ok, dodanie ClearSystemCache w rzeczywistości działa; z jakiegoś powodu nie zadziałało za pierwszym razem, ale teraz działa. Działa nawet w wersji równoległej. Dzięki! –