2009-07-13 19 views
8

Kısa bir süre önce bir Vector 3 dersi yazdım ve bir arkadaşa incelemek için normalize() işlevimi gönderdim. İyi olduğunu söyledi, ancak mümkün olduğunda karşılıklı olarak çoğalmalıyım çünkü "çarpma, bölme işleminden daha ucuzdur".Neden bölündükten daha ucuz çarpar?

Sorum şu ki, neden bu?

+1

Ints veya floats ile mi çalışıyorsunuz? – Uri

+0

Vektör3 için tam sayı. Niye ya? – jkeys

+0

Kopyala: http://stackoverflow.com/questions/655537/is-multiplying-the-inverse-better-or-worse – womp

cevap

9

o donanım daha kolay uygulayabileceği temel operasyonları açısından Bir düşünün - karşılaştırmak, vardiya toplama, çıkarma. Çarpıcı bir kurulumda bile çoğaltma, daha basit ilk adımlar gerektirir - artı, daha hızlı olan algoritmaları geliştirir - örneğin, here'a bakın ... fakat donanım genellikle bunlardan yararlanamaz (belki de son derece özel donanımlar hariç). Örneğin, wikipedia URL'sinin dediği gibi, "Toom-Cook, beş büyüklükteki N çarpımının maliyeti için bir boyut-N küplü çarpma yapabilir" - çok büyük sayılar için oldukça hızlıdır (Fürer'in algoritması, oldukça yeni bir gelişme, Θ(n ln(n) 2Θ(ln*(n))) yapabilir - yine wikipedia sayfasını ziyaret edin ve buradan bağlantı kurun). Tekrar - -

Bölümü olarak, sadece intrisically yavaş olduğunu wikipedia başına; En iyi algoritmalar (bazıları HW'de uygulanmaktadır), çarpma için en iyi algoritmalar kadar karmaşık ve karmaşık olmadıkları için; --- çarpımlara bir mum tutamazlar.

Just-so-büyük değil sayılarla sorunu ölçmek için, burada gmpy ile bazı sonuçlar, eğilimi kolay kullanımlı Python sarıcı etrafında GMP, aritmetik oldukça iyi uygulamaları mutlaka latest- olmasa da var olan ve en büyük hırıltılar.

$ python -mtimeit -s'import gmpy as g; a=g.mpf(198792823083408); b=g.mpf(7230824083); ib=1.0/b' 'a*ib' 
1000000 loops, best of 3: 0.186 usec per loop 
$ python -mtimeit -s'import gmpy as g; a=g.mpf(198792823083408); b=g.mpf(7230824083); ib=1.0/b' 'a/b' 
1000000 loops, best of 3: 0.276 usec per loop 

Gördüğünüz gibi, hatta bu küçük boyut (sayılarda bit) sayısı az, ve tam olarak aynı hız takıntılı insanlar tarafından optimize kütüphaneler ile: Pro yavaş (ilk nesil ;-) Macbook üzerinde Karşılıklı çarpma, bölünmenin aldığı sürenin 1/3'ünü kurtarabilir.

Bu birkaç nanosaniye bir hayat ya ölüm sorunu vardır, ama bunlar olduğunda, ve tabii ki tekrar tekrar aynı değere bölerek IF sadece nadir durumlarda olabilir (1.0/b uzakta amorti etmek operasyon!), o zaman bu bilgi bir hayat kurtarıcı olabilir. aynı damarda çok

(- ve Horner en scheme polinom hesaplama için çok tercih edilir - x*x sıklıkla [Python ve Fortran gibi bir ** "yükseltmek güce" operatörünü sahip dillerinde] x**2 kıyasla zaman kazandıracak art arda güç operasyonlarına! -). geri ilkokula düşünüyorsanız, o çarpma daha ve bölme daha zordu Hatırlayacaksınız

+0

[Montaj talimatları ile ilgili yararlı bilgiler.] (Http://www.agner.org/optimize/instruction_tables.pdf) – nonsensickle

0

(Float) bölümü için CPU işlemi, çarpma işleminden çok daha karmaşıktır. CPU daha fazlasını yapmak zorunda. Donanım hakkında bilgili olmaktan çok uzaktayım, ancak genel bölünme uygulaması hakkında birçok bilgi bulabilirsiniz (örneğin, newton-raphson algoritmalarına dayanarak).

Ben de hep CPU performansı elde etmek yerine bölünmenin karşıtının çarpma kullanma konusunda dikkatli olacaktır: onlar tam olarak aynı sonuçlar vermeyebilir. Bu, uygulamanıza bağlı olarak değişebilir veya olmayabilir.

6

çarpma daha zordu. İşlemler CPU için farklı değil.

Hatırlama da üç kez bir kez tersi ile hesaplamak ve kullanmak sürece, bir hız yukarı gözle görülmeyecek kadar tersi ile hesaplanması, bir bölümü içerdiğini.

+3

+1, karşılıklı önbelleğe alma gereksinimi ile ilgili önemli açıklama için. – Thilo

+0

İlkokul için olduğu gibi, eklemeyi (hala) çıkarma işlemini eklemekten daha zor buldum, ancak bu ikisi bir CPU için aynı gibi görünüyor. ;-) – Thilo

+0

@Thilo: Bir çıkarma işlemi yapmanız gerektiğinde, ikinci işleneni reddetmeniz yeterlidir ve daha sonra bunun yerine "daha kolay" ekleme yapabilirsiniz. :-) –