2013-08-26 13 views
8

Mam trochę kodu w F #, który działa dobrze pod .net, ale przepełnia stos pod Mono. Powiązanym problemem jest to, że wydaje się, że robi tak długo, zanim przestrzeń stosu, podobno do niego dostępna, się skończy (zaczyna się od System.Threading.Thread (ts, 1000000000)). O ile mogę powiedzieć, fałd, w którym umiera, jest rekursywny, a ślad stosu wygląda tak, jakby optymalizacja ogona nie była wykonywana. Używam wersji 3.2.1 z opcją --optimize = tailc.Ogony w Mono

Czy ktoś wie dokładnie, jakie rodzaje połączeń ogonowych usuwają stos wywołujący, a które nie? Lub alternatywnie, jak przydzielić więcej żetonów? Wielkie dzięki.

Jestem świadomy Tailcall elimination in Mono

EDIT: tu jest zarys kodu na żądanie w komentarzach. Jest to część fałdu na dużej strukturze danych, ale wadliwy stacktrace ma tylko mapk i myfold na nim.

let rec myfold f x k = 

    let rec mapk xs k = 
    match xs with 
    [] -> k [] 
    | x::xs -> mapk xs (fun xs' -> myfold f x (fun x' -> (x' :: xs') |> k)) 

... 

mapk (...) (... >> k) 
+0

Na jakiej platformie działa się Mono? (FreeBSD? OS X? Linux?) –

+0

Linux. 8-rdzeniowy procesor AMD z 64 Gb pamięci RAM, jeśli to robi różnicę. –

+0

Jakiego rodzaju funkcji rekursywnej ogon masz? Czy nazywa się sama, czy też nazywa inną funkcją? (lub czy używają kontynuacji?) (próbuję po prostu dowiedzieć się, co może pójść źle - ponieważ niektóre wywołania ogona są zoptymalizowane przez kompilator F #.) –

Odpowiedz

1

O ile mi wiadomo, --optimize=tailc nie jest obsługiwaną flagą kompilatora F #.

Nie sądzę, że istnieje sposób, aby włączyć/wyłączyć wsparcie optymalizacji tailcall w Mono (z linii poleceń, tak); flaga kompilatora F # umożliwiająca optymalizacje ogόlnych wywołań to --tailcalls+, ale zgodnie z Compiler Options (F#), która jest domyślnie włączona.

Myślę, że najlepszym wyborem, aby to rozwiązać to:

+0

Tailc to opcja "optymalizacji" Mono. Używam - tailcalls podczas uruchamiania F #. Podejrzewam, że zgłoszenie błędu przyniosłoby skutek odwrotny do zamierzonego, ponieważ Mono jest dobrze znany z tego, że nie robi poprawnie poprawek (lub do niedawna). Ale gdyby ktoś dokładnie wiedział, kiedy działa istniejące wsparcie, a kiedy nie, byłoby to bardzo pomocne. –

+3

Jeśli nie zgłosisz błędu, to w jaki sposób ktoś by to naprawił? – 7sharp9