Hesaplamak 2 ** x exp (x) 'den daha hızlı mı?


12

Bu soruyu sormamın yanı sıra sorduğum gerçeği açıkça anlayacak olan naifeyi affedin.

Matematikçiler teoride en basit / en güzel temel olduğu için tipik olarak kullanırlar (matematik nedeniyle). Ancak bilgisayarlar her şeyi ikili olarak yapıyor gibi görünüyor, bu yüzden bir makinede hesaplamak daha hızlı mı?exp2**xMath::exp(x)


7
Ne tür bir numaradan bahsediyorsun? Arbitary-size tamsayı? Sabit boyutlu kayan nokta? Keyfi hassasiyetli kayan nokta?
Gilles 'SO- kötü olmayı kes

@Gilles İyi bir nokta. Farkın önemli olduğunu fark etmedim.
izomorphismes

3
Bazı Casio cep hesap makinelerinde, e olmayan bir sayının günlüğü ve gücünün ln /
exp'den

2
Kör olma riski için, ikisini de zamanlamayı ve hangisinin daha hızlı olduğunu görmeyi denediniz mi? Yoksa hızın karmaşıklık duygusundan mı bahsediyorsunuz? O(f(n))
jmite

1
Dil en hızlı yolu seçmekle görevlidir ve bu konuda iyi bir iş çıkarır. Sadece en yüksek hızın gerekli olması ve ölçümlerin , bu tür şeyler hakkında endişelenmeniz durumunda bunun performansla ilgili olduğunu göstermesi durumunda
vonbrand

Yanıtlar:


18

Bu CS değil, Stackoverflow olduğundan, sayısal analiz ve (işleri basit tutmak için) özellikle IEEE-754 kayan nokta hakkında bir soru sorduğunuzu varsayacağım. Bu durumda, sorunuzun cevabı kısmen "daha kolay" ile kastettiğiniz anlama, kısmen de sistem detaylarına bağlıdır.

Bildiğim modern CPU'ların hiçbiri, ya işlemi için beklediğiniz şeyi yapan bir talimat içermiyor (bundan sonra arayacağız , C'deki olağan adı) veya ( ). Her ikisi de kütüphane işlevleri kullanılarak uygulanır.2 xexexp2xexp2

Transandantal operasyonlar için tüm sayısal yöntemlerde olduğu gibi, dikkate alınması gereken birkaç özel durum vardır:

exp(NaN) = NaN
exp(+Inf) = +Inf
exp(-Inf) = 0

Bununla birlikte, sorunu biraz daha az karmaşık hale getiren başka bir şey daha vardır: yararlı alan oldukça küçüktür. Binary32 için, exp(x)eğer underflows ya da öylesine, ve eğer taşıyor kadar. Çünkü Alışılmadık transandantal operasyonlar için, biz de, normalin altında durumda göz ardı edebilirsiniz ayırt edilemez ise normalin altında. Yukarıdakilerin tümü de geçerlidir , ancak alan biraz farklıdır.x > 88,7x<104x>88.7exp(x)1.0xexp2

Sezginiz, çoğu uygulamanın hesaplamasında doğrudur . Ancak, ile çarpmanın maliyeti , diğer bilgisayarlarla karşılaştırıldığında önemsizdir . Tipik bir yöntem elemanları içeren önceden hesaplanmış bir tablo kullanır :1ex=2x/ln2 K1ln2exp2K

exp2(x)=2n×T[j]×P(y)

burada , tamsayı kısmıdır, tablosu, aralığındaki tüm için değerlerini içerir ve , miktar polinom yaklaşımıdır (quartic, binary32 için yeterlidir32 ) aralığında . sadece üs manipüle beri parçası ucuz. bir arama tablosu. Yani muhtemelen operasyonun pahalı bir parçası olacak.x T 2 j / K j [ 0 , K ) P 2 x [ 0 , 1nxT2j/Kj[0,K)P2x2nTP[0,1K)2nTP

Intel x 86 kayan nokta birimleri olarak adlandırılan bir talimatı içerir bu şeyiyle işaret olmalıdır f2xm1hesaplar, için aralığında . Bununla birlikte, modern bir CPU'da, bu oldukça pahalı ve boru hattına bağlı olmayan bir talimattır ve bunu kullanmanız kesinlikle önerilmez. As Intel Optimizasyon Referans Kılavuzu Bölüm 3.8.5 haklı notlar:x [ - 1 , 1 ]2x1x[1,1]

X87 aşkın talimatları desteklese de, aşkın fonksiyonun yazılım kütüphanesi uygulaması birçok durumda daha hızlı olabilir.

Edit: Yorumlarda IEEE 754-2008'de kullanılan yeni terminolojiden bazılarını açıklamamız gerektiği belirtildi. Dilin bir kısmı 1985 ve 1987'den beri değişti ve çoğu insan eski jargona çok daha aşina.

"Binary32" ve "binary64" terimleri, eski standardın sırasıyla "tek" ve "çift" olarak adlandırdığı 32 bit ve 64 bit ikili kayan noktalı sayıların yeni adlarıdır.

"Alt normal sayı" terimi, önceki "denormal sayı" veya "denormalize sayı" teriminin yerine geçer .


"subnormal" dediğinizde - açıkça "sub-Gaussian" anlamına gelmez; "[bazı tipiklik ölçütlerinden daha kötü" mü demek istediniz?
isomorphismes

2
@isomorphismes Burada, 'normal olmayan' şamandıraların nasıl uygulandığı ile ilgilidir. Wikipedia'daki denormal sayılara bakın .
Paul Manta

Bu arada, "tipik yöntemi" biraz fazla basitleştirdim. Burada sunulan yönteme yalnızca bir küçük (ve anlaşılması oldukça kolay) uzantı kullanarak exp2 () ve exp () 'yi ulp doğruluğu ile uygulamak mümkündür, ancak küçük, anlaşılması kolay uzantının açıklaması muhtemelen cevap!
Takma ad

6

2**x2x<<1 << x


4
aslında değil. x belki bir kayan noktalı tür
phuclv

1
x

Bir xtamsayı değilse (diyelim ki 20.75), mantis 2ve üssünü xen doğru tahmin ( yuvarlatılmış gösterim mümkün değildir) olarak yuvarlanmış değere ayarlarsınız . Hangisi de 'pow´'den çok daha hızlı.
Damon

1

2**xTamsayılarda bir işlev varsa , Stephen'ın cevabına katılıyorum, vardiya daha ucuz. Ancak tipik olarak kayan nokta üstellemesini göstermek için 2^xve olduğunu görüyorum **. Bu durumda, ben arasındaki benzer performans beklenir **ve ^hem beri expve pow(için temel çalışma **) hem transandantal yaklaşım operasyonlardır.


İlginç, **kayan noktalı versiyonun eşanlamlı olarak kabul edildiğini bilmiyordum (ve aptalca, ikisinin farklı olacağını unutmuştum).
izomorphismes

1

2 ^ x = e ^ (x * ln 2) ve e ^ x = 2 ^ (x * log2 (e)) olduğundan, fazla bir fark beklemezsiniz.

Sıfıra yakın x için, genellikle yuvarlama hatasını küçük tutarken mümkün olduğunca çabuk kesmek için optimize edilmiş bir polinom e ^ x = 1 + x + x ^ 2/2 + x ^ 3/6 ... kullanılır. . Açıkçası 2 ^ x hesaplamak için çok küçük, çok küçük bir yavaştır. "x, 0'a yakın" genellikle x (sq) (1/2) <= e ^ x <= sqrt (2) değeridir. X aralığının sınırlandırılması, polinom derecesinin çok yüksek seçilmesine gerek kalmamasını sağlar.

Daha büyük x için, x = x '+ x' 'girerek x ^ x tamsayı ve -0.5 <= x' '<= 0,5 olur. 2 ^ x 'daha sonra doğru bit deseniyle bir kayan nokta sayısı yapılarak ve 2 x x' 'küçük x için e ^ x yöntemi kullanılarak hesaplanır. Burada, 2 ^ x biraz daha hızlı. Dahası, eğer x büyükse (örneğin x = 100.3), x'i log2 (e) ile çarpmak kabul edilemez bir yuvarlama hatası getirecektir (çünkü çok daha az kesirli bit vardır), bu yüzden daha fazla dikkat gösterilmelidir.

Ve umarım iyi bir kütüphane fonksiyonu x <= y, e ^ x <= e ^ y ve 2 ^ x <= 2 ^ y olduğunda, yuvarlama hataları ne olursa olsun. Bu tür şeyleri başarmak zor olabilir.


0

Bir bilgisayardaki matematiğin farklı yazılımlar tarafından farklı şekillerde yapıldığını anlamalısınız, umarım tutarlı cevaplar bulurlar. Çoğu yazılıma baktığımda, bilgisayarların iyi davrandığını düşünüyorum - bilgisayarlar 0 ve 0 için bile uzun bir yol hesaplayacaktır. Sorun, özel durumlarda dijital bilgisayarlarda ücretsiz olarak gerçekleşmeyen "tanıma" yı içermesidir. Bu, yalnızca cevaba sahip olmanın işleri hızlandıracağı durumlarda "en fazla" optimizasyonun gerçekleşeceği anlamına gelir. Ancak bu durumlarda son derece iyi ortaya çıkacaktır. Ayrıca, doğru cevabı almak için birkaç farklı tanıma yapılması gerekebileceğini unutmayın. Buna hız optimizasyon seviyeleri denir ve GNU "C" olarak adlandırılan çoğu yazılım temelinde bu maksimum profesyonel düzeyde gerçekleşmiştir. Bunun nedeni, burada yazılımdan yazılıma ve makineden makineye çalışma süresindeki küçük farklılıkların kalite kabul rakamları olarak kullanılmasıdır. Diğer tercümanlarda genellikle sadece bir "sıfır bayrağı" oluşması durumunda önceki hesaplamaların yan etkisi tanınmayı hızlandıracaktır. 0 * x => C0 gibi.

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.