2013-03-22 9 views
6

Niedawno przeczytałem ten temat NaN wartości w SSE operacji arytmetycznych:Jak upewnić się, że NaNs rozprzestrzeniają się podczas używania samoistnego SSE?

wynik operacji arytmetycznych działających na dwa nie liczbą (NaN) argumentów jest niezdefiniowany. Dlatego operacje zmiennoprzecinkowe używające argumentów NAN nie będą zgodne z oczekiwanym zachowaniem odpowiednich instrukcji montażu.

Źródło: http://msdn.microsoft.com/en-us/library/x5c07e2a(v=vs.100).aspx

Czy to znaczy, że, powiedzmy, dodanie dwóch __m128 wartości może konwertować NaN do rzeczywistego?

Jeśli obliczenia opierają się na wartości NaN, potrzebuję również końcowego wyniku, który będzie również NaN. Czy jest jakiś sposób to zrobić?

+1

Myślę, że to zbyt pedantyczne. Instrukcje SSE zmiennoprzecinkowe powinny być zgodne z IEEE zmiennoprzecinkowe zachowanie raczej ściśle, chyba że robisz rzeczy takie jak spłukiwanie lub coś w tym rodzaju. – Mysticial

+1

@Mysticial: Nie oznacza to, że instrukcje SSE nie zapewnią oczekiwanych rezultatów. Mówi się, że kompilator może nie używać instrukcji SSE do implementacji wewnętrznej encykliki typu SSE. –

+1

@EricPostpischil Widzę, co mówisz. Ale do tej pory nie widziałem jeszcze czegoś takiego. Więc nie jestem do końca przekonany o tym. – Mysticial

Odpowiedz

5

Kiedy interpretuję ten tekst, mówię, że kompilator oferuje różne elementy wewnętrzne, które w przybliżeniu odpowiadają instrukcjom SSE. Ogólnie można się spodziewać, że kompilator użyje instrukcji SSE do implementacji właściwości wewnętrznych. Jednak nie jest to ścisłe. Rzeczywistość faktycznie określa operacje w pewnym abstrakcyjnym modelu obliczeń; nie określają bezpośrednio instrukcji SSE. W tym abstrakcyjnym modelu wynik działania na dwóch NaNach (dziwne, że nie pozwala na jeden NaN i jeden numer) jest niezdefiniowany. Dlatego wynik, na jaki otrzymasz, na przykład dodanie dwóch NaNów może nie być NaN.

W szczególności operacje w modelu abstrakcyjnym podlegałyby optymalizacji kompilatora, a te optymalizacje mogłyby skutkować czynnościami innymi niż instrukcje SSE (obliczenia w czasie kompilacji, pominięte instrukcje, jeśli kompilator może wywnioskować, że NaN są obecne, więc robi to nie trzeba faktycznie wykonywać add, et cetera).

Wygląda na to, że jeśli chcesz zagwarantować semantykę podaną dla instrukcji SSE, możesz napisać w języku asemblerowym, zamiast używać wewnętrznego komponentu w kompilatorze Microsoftu.

Chciałbym, aby producenci przestali dawać lekką semantykę zmiennoprzecinkową. Trudno jest wykonywać inżynierię w przypadku braku dobrze określonych zachowań.

+1

Istnieje jedna względnie łagodna możliwość. Może zawsze wytwarzać NaN, ale niekoniecznie taki, który w spójny sposób odnosi się do wejściowych NaN.W takim przypadku pomocne byłoby udokumentowanie tego. –

+0

Wygląda na to, że może to stanowić problem tylko wtedy, gdy kompilator mógłby sprawdzić dwie wartości na 'NaN' i był nieodparty powód, aby kompilator mógł z niego skorzystać, imho: ten pierwszy nie wydaje się prawdopodobny a tego ostatniego trudno jest wymyślić z przykładem ... –

+2

@ PatriciaShanahan: To wydaje się prawdopodobne. Który z dwóch wejściowych NaN instrukcji zwraca często zależy od kolejności operandów, a kompilator może nie zachowywać porządku od właściwości do instrukcji. Doprowadziłoby to do konieczności udokumentowania, że ​​który z dwóch NaNs jest zwracany, jest niezdefiniowany, a niechlujna obsługa tego może skutkować dokumentacją stwierdzającą, że wynik działania na dwóch NaN jest niezdefiniowany. Niemniej jednak dokumentacja mówi, co ona mówi. –

Powiązane problemy