Java'da “strictfp” anahtar kelimesini ne zaman kullanmalıyım?


258

Bunun ne yaptığını araştırdım, ancak strictfpanahtar kelimeyi Java'da ne zaman kullanacağınız konusunda gerçekten bir örneği var mı? Herkes bunun için bir kullanım buldu mu?

Sadece kayan nokta operasyonlarıma koymanın herhangi bir yan etkisi var mı?


1
Performansa tekrar ihtiyaç duyduğunuzdan daha fazlasına ihtiyacınız yoksa, her zaman.
Antimon

1
@Antimony - veya hassasiyet / doğruluk. Örneğin, x86 / x64, dahili olarak 80 bit kayan nokta yazmaçları kullanır, bu nedenle sonuç, uzun bir hesaplama için strictfp olmadan daha doğru olur.
Robert Fraser

1
@Robert Aslında, teknik özellikler mantisin sınırlı hassasiyetini garanti ediyor. Tek fark, çift yuvarlama nedeniyle nadir durumlarda farklılık gösteren normalden daha büyük bir üs hassasiyeti kullanabilmesidir.
Antimon

Bu faydalı değiştiriciyi eklemin her tarafına serpme seçeneğine ek olarak, yeni sfloat ve sdouble ilkel katı veri türlerinin iyi bir fikir olabileceğini düşünüyorum.
19'19Riley

Yanıtlar:


274

Strictfp, her platformdaki kayan nokta hesaplamalarınızdan tamamen aynı sonuçları almanızı sağlar. Strictfp kullanmıyorsanız, JVM uygulaması mevcut olduğunda ekstra hassasiyet kullanmakta serbesttir.

JLS'den :

FP katı ifadesinde, tüm ara değerler kayan değer kümesi veya çift değer kümesi öğeleri olmalıdır, bu da tüm FP katı ifadelerinin sonuçlarının, tek ve çift formatlar kullanılarak temsil edilen işlenenlerde IEEE 754 aritmetiği tarafından tahmin edilenler olması gerektiğini ima eder. . FP-katı olmayan bir ifade içinde, bir uygulamanın ara sonuçları temsil etmek için genişletilmiş bir üs aralığı kullanması için bir miktar boşluk verilir; kabaca söylemek gerekirse, net etki, bir hesaplamanın şamandıra değer setinin veya çift değer setinin münhasır kullanımının taşma veya taşmaya neden olabileceği durumlarda "doğru cevabı" üretebilmesidir.

Başka bir deyişle, bu, Bir Kez Yaz-Çalıştır-Her Yerde aslında bir kez Yaz-Al-Eşit-Yanlış-Sonuçlar-Her Yer anlamına geldiğinden emin olmakla ilgilidir .

Strictfp ile sonuçlarınız taşınabilir, onsuz doğru olma olasılığı daha yüksektir.


28
Tekrarlanabilir bilimsel sonuçlar ve bit kesin birim testleri için kullanın.
Aleksandr Dubinsky

1
"Eğer varsa yok strictfp kullanın JVM uygulama Müsait ekstra hassas kullanmak serbesttir" - Yaptığınız kötü bir şey gibi geliyor: P
AMDG

Kesinlikle @LinkTheProgrammer olabilir kötü bir şey olabilir
Tim

@TimCastelijns Sanırım Happy Wheels referansınız mı? Tekrarlar tuş vuruşlarını kaydeder; FP-math uygulaması hassas çeşitliliği nedeniyle, tekrarlar sadece benzer donanımlarda doğrudur. Kayan nokta matematik değişkenliğinin neden olduğu daha gerçekçi bir problemi adlandırabilir misiniz? Belki bir parçacık simülatörü hayal edebiliyorum, ama başka ne var?
AMDG

Yani bu, birden fazla platformun yer aldığı üretimde daima solidfp kullanmamız gerektiği anlamına mı geliyor?
beatrice

65

Vikipedi aslında bu konu hakkında iyi bir makale var burada Java şartnamesine bağlantıya sahip.

Satırlar arasında okuma, sonuç belirtmezseniz strictfp, JVM ve JIT derleyicisinin kayan nokta hesaplamalarınızı istedikleri gibi hesaplamak için lisansa sahip olmasıdır. Hız açısından, büyük olasılıkla hesaplamayı işlemcinize devredecektir. Açıkken strictfp, hesaplamalar IEEE 754 aritmetik standartlarına uymak zorundadır, bu da pratikte muhtemelen JVM'nin hesaplamayı yapacağı anlamına gelir.

Öyleyse neden kullanmak istesin strictfp? Görebildiğim bir senaryo, temel donanım veya CPU ne olursa olsun tüm kayan nokta hesaplamalarının belirleyici olması gereken dağıtılmış bir uygulamada (veya çok oyunculu oyunda). Takas nedir? Büyük olasılıkla yürütme süresi.


5
“Ara sonuçları temsil etmek için genişletilmiş bir üs aralığı” “kayan nokta hesaplamalarınızı istedikleri gibi hesaplama lisansı” değildir ve pratikte, strictfphesaplamalar bile 8087 FPU'yu bile kullanmaz. O zaman sadece biraz bakım gerekli. Bkz. Stackoverflow.com/questions/18496560/…
Pascal Cuoq

@PascalCuoq re: "Kayan nokta hesaplamalarınızı istedikleri gibi hesaplamak için lisans" ı kabul ediyorum . Herhangi bir şey varsa, bunun tersi doğru gibi görünmektedir, çünkü strictfpIEEE 754 standardına uyumu sağlar (böylece tüm platformlarda aynı sonucu elde edersiniz). Görebildiğim tek dezavantaj, yerel donanımınızda gerçekten iyi bir FPU'ya sahip olmanın avantajlarını kaybedebileceğinizdir.
daktilo

25

Her şey bir hikaye ile başladı,

Java James Gosling, Herbert ve ekibinin geri kalanı tarafından geliştirilirken. Akıllarında platform bağımsızlığı denilen çılgın bir şey vardı . Yapmak istedilerMeşe (Java)o kadar iyi ki, farklı işletim sistemlerini çalıştıran farklı talimat setlerine sahip herhangi bir makinede tam olarak aynı şekilde çalışır. Ancak, programlama dillerinde kayan nokta ve çift olarak da bilinen ondalık nokta sayılarıyla ilgili bir sorun vardı. Bazı makineler hedefleme verimliliği oluştururken, geri kalanı doğruluk hedeflemiştir. Bu nedenle, daha sonraki (daha doğru) makineler 80 bit olarak kayan nokta boyutuna sahipken, eski (daha verimli / daha hızlı) makineler 64 bit iki katına sahipti. Ancak bu, platformdan bağımsız bir dil oluşturma temel fikrine aykırıdır. Ayrıca, bir kod bazı makinelerde (64 bit boyuta sahip) ve başka tür bir makinede (80 bit boyuta sahip) çalıştırıldığında hassasiyet / veri kaybına neden olabilir.

Yukarı Boyutlandırma tolere edilebilir, ancak Aşağı Boyutlandırma olamaz. Bu yüzden katı bir kavram, yani katı kayan nokta ile karşılaştılar . Bu anahtar kelimeyi bir sınıf / işlevle kullanırsanız, kayan noktası ve çiftleri herhangi bir makineye göre tutarlı bir boyuta sahiptir. yani sırasıyla 32/64 bit.


8
strictfp Java 1.2'de tanıtıldı. Bu, meşenin tasarlandığı zamandan çok daha geç oldu.
Thorbjørn Ravn Andersen

"ondalık nokta sayıları kayan nokta olarak da bilinir" - Ondalık taban 10 anlamına gelir ve kayan nokta gösterimleri ile ilgisi yoktur.
aioobe

21

İşte birkaç referans:

  • Strictfp kullanma (JDC Teknik İpucu)
  • jGuru: strictfp değiştiricisi ne için? Ne zaman kullanmayı düşünürdüm?

    Temel olarak, her şey kaynıyor, kodunuzdaki kayan nokta ifadelerinin sonuçlarının hızlı veya tahmin edilebilir olup olmadığına bakıp bakmamanızdır. Örneğin, kodunuzun birden çok platformda tutarlı olması için kayan nokta değerleri kullanan yanıtlara ihtiyacınız varsa kullanın strictfp.

  • strictfp - Java Sözlüğü

    Kayan nokta donanımı, Java spesifikasyonunun gerektirdiğinden daha hassas ve daha geniş bir değer aralığı ile hesaplar. Bazı platformların diğerlerinden daha fazla hassasiyet vermesi kafa karıştırıcı olacaktır. Kullandığınızda strictfpbir yöntem veya sınıfına değiştirici, derleyici kodu oluşturduğu tüm platformlarda aynı sonuçlar için Java spec sıkı yapışır. Olmadan strictfp, biraz gevşek, ama 80 bit hassasiyet vermek için Pentium'daki koruma bitlerini kullanacak kadar gevşek değil.

  • Ve son olarak gerçek Java Dil Spesifikasyonu, §15.4 FP-sıkı İfadeler :

    FP katı ifadesinde, tüm ara değerler kayan değer kümesi veya çift değer kümesi öğeleri olmalıdır, bu da tüm FP katı ifadelerinin sonuçlarının, tek ve çift formatlar kullanılarak temsil edilen işlenenlerde IEEE 754 aritmetiği tarafından tahmin edilenler olması gerektiğini ima eder. . FP-katı olmayan bir ifade içinde, bir uygulamanın ara sonuçları temsil etmek için genişletilmiş bir üs aralığı kullanması için bir miktar boşluk verilir; kabaca söylemek gerekirse, net etki, bir hesaplamanın şamandıra değer setinin veya çift değer setinin münhasır kullanımının taşma veya taşmaya neden olabileceği durumlarda "doğru cevabı" üretebilmesidir.

Yine de kişisel olarak hiç kullanmadım.


12

Bahsedilen diğer cevaplar, ara kayan nokta sonuçlarının IEEE spesifikasyonuna uymasına neden olmaktadır. Özellikle x86 işlemciler, ara sonuçları IEEE spesifikasyonundan farklı hassasiyetle saklayabilir. JIT belirli bir hesaplamayı optimize ettiğinde durum daha karmaşık hale gelir; talimatlar her seferinde farklı olabilir, bu da biraz farklı yuvarlama ile sonuçlanır.

Strictfp tarafından yapılan ek yükün çok işlemciye ve JIT'e bağlı olması muhtemeldir. SSE2 ile ilgili bu wikipedia makalesi , sorun hakkında bir fikir sahibi gibi görünüyor. Yani JIT bir hesaplama yapmak için SSE talimatları üretebiliyorsa, tightfp'nin herhangi bir ek yükü olmayacak gibi görünüyor.

Şu anki projemde rigfp kullandığım birkaç yer var. Potansiyel kozmik ışınların piksel değerlerinden çıkarılması gereken bir nokta vardır. Dışarıdaki bazı araştırmacılar önlerinde aynı piksel değerine ve kozmik ışına sahipse, yazılımımızla aynı sonuç değerini almalıdırlar.


8
  • strictfp, IEEE 754 uyarınca kayan nokta hesaplamalarını kısıtlayan bir değiştiricidir.

  • Bu, "public strictfp class StrictFpModifierExample {}" gibi tüm sınıflarda veya "public strictfp void example ()" yönteminde kullanılabilir. Sınıfta tüm yöntemlerden daha fazla kullanılırsa, IEEE 754'ü izleyecek ve yöntemde kullanılırsa belirli yöntem kullanılacaktır. IEEE 754'ü takip edin.

  • Neden kullanılır ?? ::: Farklı platformlar, java spesifikasyonunun gerektirdiğinden daha hassas ve daha fazla değer aralığı ile hesaplanan farklı plaka formlarında farklı çıktılar üretebilecek farklı kayan nokta donanımına sahip olduğundan, farklı olursa olsun aynı çıkışı onaylar plateforms

  • strictfp ayrıca genişletilmiş hassas kayan nokta işlemlerinin hızından ve hassasiyetinden yararlanmayı sağlar.

  • Kayan nokta hesaplamaları yaparken kullanabileceğimiz bu anahtar kelimenin bir dezavantajı yoktur

  • Son nokta - IEEE754 kısaca IEEE 754, kayan nokta hesaplamaları ve kayan nokta değerlerinin tek (32-bit, Java floatlarında kullanılan) veya çift (64-bit, Java'da kullanılan) için standart yöntemi tanımlar Ara hesaplamalar ve genişletilmiş hassas biçimler için normları da tanımlar.


2

strictfpbir anahtar kelimedir ve sınıflar veya yöntemler için erişilemez bir değiştirici olarak kullanılabilir (ancak hiçbir zaman değişken değildir). Bir sınıfı işaretlemek, sınıftaki strictfpherhangi bir yöntem kodunun kayan noktalar için IEEE 754 standart kurallarına uygun olacağı anlamına gelir.

Bu değiştirici olmadan, yöntemlerde kullanılan kayan noktalar platforma bağlı bir şekilde davranabilir. Bununla birlikte, JVM'nin üzerinde çalıştığı alt platformdan bağımsız olarak kayan noktalarınızın nasıl davranacağını tahmin edebilirsiniz. Dezavantajı, altta yatan platform daha fazla hassasiyeti destekleyebiliyorsa, bir strictfpyöntemin bundan yararlanamayacağıdır.

Bir sınıfı olarak bildirmezseniz, bir yöntemi olarak bildirerek yine de yöntem bazında davranış strictfpelde edebilirsiniz .strictfpstrictfp

~ Java ™ 6 için SCJP Sun® Sertifikalı Programcı - Kathy Sierra ve Bert Bates ~


0

Aşağıdaki örnek bunu daha net anlamada yardımcı olabilir: Java'da herhangi bir işlem için kesin bilgi aramayı kullandığımızda, örneğin çift num1 = 10e + 102 yaparsak; çift ​​num2 = 8e + 10; sonuç = num1 + num2;

        The output will be so long and not precise, becasue it is precissed by the hardware e.g JVM and JIT has the license 
        as long as we dont have specify it Strictfp

Marking it Strictfp will make the result Uniform on every hardware and platform, because its precised value will be same
One scenario I can see is in a distributed application (or multiplayer game) where all floating-point calculations need to 
be deterministic no matter what the underlying hardware or CPU is.

0

'strictfp' anahtar kelimesi, Java'daki kayan nokta hesaplamalarının (kayan nokta veya çift) kesinliğini IEEE'nin 754 standardına açıkça uyarlamak için kullanılır. Strictfp anahtar sözcüğü kullanmazsanız, kayan nokta hassasiyeti hedef platformun donanımına bağlıdır.

Bir arabirim veya sınıf strictfp ile bildirilirse, o arabirim veya sınıf içindeki tüm yöntemler ve iç içe türler dolaylı olarak strictfp olur.

Referans bağlantısı

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.