Bu XOR değeri takas algoritması hala kullanımda mı yoksa kullanışlı mı?


25

Bir anabilgisayar montajcısı programcısı çalışmaya başladığımda, geleneksel algoritmasını kullanmadan nasıl değer değiştirdiklerini bana gösterdi:

a = 0xBABE
b = 0xFADE

temp = a
a = b
b = temp

İki değeri takas etmek için kullandıkları - bir parçadan büyük bir ara belleğe - şuydu:

a = 0xBABE
b = 0xFADE

a = a XOR b
b = b XOR a
a = a XOR b

şimdi

b == 0xBABE
a == 0xFADE

Bu, üçüncü bir sıcaklık tutma alanına ihtiyaç duymadan 2 nesnenin içeriğini değiştirdi.

Sorum şu: Bu XOR takas algoritması hala kullanılıyor mu ve hala uygulanabilir mi?


50
Hala görüşme ve kötü görüşme soruları göstermek için geniş kullanımda; bu konuda.
Michael Borgwardt

4
Bu numara gibi bir şey mi: a = a + b, b = ab, a = ab?
Pieter B

4
@ PieterB evet, ikisi de bu stackoverflow.com/questions/1826159/…
jk.

Yani ... Bir kayıt defteri kaydedin, ancak 3 talimat daha ödeyin. Temp sürümü zaten daha hızlı olacağını düşünüyorum.
Billy ONeal,

1
@ MSalters değer takası, x86 komutundan dolayı x86'da başından beri bir sorun olmamıştır. OTOH 2 bellek yerini değiştirirken 3 xchgs :) gerektiriyor
Netch

Yanıtlar:


41

Kullanım sırasında xorswap, her değişkeni sıfıra xorçeviren kendisiyle olduğu için, söz konusu değişkeni sıfırlayan fonksiyona her iki argümanla aynı değişkeni sağlama tehlikesi vardır . Elbette bu, kullanılan algoritmadan bağımsız olarak istenmeyen davranışlara yol açar, ancak davranış ilk bakışta şaşırtıcı olabilir ve açık olmayabilir.

Geleneksel olarak xorswap, kayıtlar arasında veri değişiminde düşük seviye uygulamalar için kullanılmıştır. Uygulamada, kayıtlardaki değişkenleri değiştirmenin daha iyi alternatifleri vardır. Örneğin, Intel'in XCHGx86'sında, iki yazmacanın içeriğini değiştiren bir talimat vardır. Bir derleyici çoğu zaman böyle bir işlevin anlamını anlar (kendisine iletilen değerlerin içeriğini değiştirir) ve gerektiğinde kendi optimizasyonlarını yapabilir, bu nedenle takas işlevi kadar önemsiz bir şeyi en iyi duruma getirmeye çalışmak gerçekten hiçbir şey satın almaz uygulamada. Sorunlu alanda xorswap demenin düşük olmasının kanıtlanmış bir nedeni olmadığı sürece, açık bir yöntemi kullanmak en iyisidir.


18
Her iki değer de aynıysa, yine de doğru sonucu elde edersiniz. a: 0101 ^ 0101 = 0000; b: 0101 ^ 0000 = 0101; a: 0101 ^ 0000 = 0101;
Bobson,

1
@ GlenH7 ne dedi. -1-> +1.
Bobson,

1
Hala "xorswap kullanırken, tüm bitleri sıfıra çeviren kendisiyle xor'd olması nedeniyle söz konusu değişkeni sıfırlayan işleve aynı değişkeni sağlama tehlikesi var" gibi görünüyor. .. Kaldırılmış olması gerekmedi mi?
Chris

9
@Chris Hayır, ilk başta eğer değerler sanki aynıysa a=10, b=10, ve eğer xorswap(a,b)işe yaramazsa ve yanlış olan ve şimdi kaldırılmış olan değişkenleri sıfırlamayacağını yazmıştım . Ama eğer xorswap(a, a)öyleyse a, sıfırdan alacaktım ki başlangıçta demek istediğim, ama aptallıktı. :)
zxcdw

3
Bazı dillerde oldukça önemlidir - bunun gibi küçük küçük tehlikeler, bir şekilde göremediğiniz 100+ satır aynı adrese işaret etmek üzere ayarlanmış iki işaretçi ile uğraşırken gelecekteki hataları bulmakta zorlanır.
Drake Clarris

14

Cevabın anahtarı, derleyiciden önceki günlerde - "bir anabilgisayar montajcısı programcısının çalışması" sorusudur. İnsanlar montaj talimatlarıyla uyuştuğunda ve belirli bir donanım parçası için kesin çözümler ürettiğinde (aynı bilgisayarın başka bir modeli üzerinde çalışabilir ya da çalışmayabilir) - sabit sürücülerin zamanlaması ve tambur hafızası gibi sorunlar kodun ne kadar etkili olduğu konusunda Yazılı - eğer biri nostaljik olmak isterse , Mel'in Hikayesi'ni okuyun ).

Geçmişte bu günlerde, kayıtlar ve bellek hem azdı hem de baş mimardan başka bir bayt ya da bellek sözcüğü için yalvarmak zorunda kalmayacak herhangi bir numara, hem kodu hem de uygulama zamanını yazarken zaman kazanmıştı.

O günler geçti. Üçünü kullanmadan iki şeyi değiştirmenin püf noktası bir numaradır. Bellek ve kayıtlar hem modern bilgisayarlarda bol hem de insanlar artık derleme yazmıyorlar. Tüm numaralarımızı derleyicilerimize öğrettik ve onlardan daha iyi bir iş çıkardılar. Muhtemelen, derleyici yaptığımızdan daha iyi bir şey yaptı. Çoğu durumda, bazen bir nedenden dolayı sıkı bir döngü içindeki bazı iç bitlere derlemeler yazmamız gerekir ... ama bu bir kayıt defteri veya bellek kelimesinden tasarruf etmek değildir.

Eğer biri özellikle sınırlı bir mikrodenetleyicide çalışıyorsa yine faydalı olabilir, ancak bir takas işleminin optimize edilmesi kişinin probleminin kaynağı değildir - çok akıllıca olmaya çalışmak daha muhtemeldir.


2
Kayıtlar pek çok bağlamda pek fazla değildir. Bir işlemci geniş bir kayıt kaynağına sahip olsa bile, bir ISR'de kullanılan her kayıt önceden kaydedilmiş ve daha sonra geri yüklenmesi gereken bir kayıttır. Eğer bir ISR yirmi devir alıyorsa ve her kırk devri çalıştırması gerekiyorsa, ISR'ye eklenen her bir ilave döngü sistem performansını beş puan düşürür.
supercat

8

İşe yarayacak mı? Evet.

Kullanmalısın Yok hayır.

Bu tür bir mikro-optimizasyon şu durumlarda mantıklı olacaktır:

  • derleyicinin bunu yapmanın kolay bir yolu için ürettiği koda baktınız (ödev ve geçici) ve XOR yaklaşımının daha hızlı kod oluşturmasına karar verdiniz

  • Uygulamanızı profillediniz ve basit bir yaklaşımın maliyetini kodun netliğinden daha ağır basıyorsunuz (ve bunun sonucunda bakımdan tasarruf edersiniz)

İlk olarak, bu ölçümü yapmadığınız sürece, derleyiciye güveniyor olmanız gerekir. Yapmaya çalıştığınız şeyin semantiği açık olduğunda, değişimin yeniden düzenlenmesi de dahil olmak üzere, derleyicinin yapabileceği birçok püf noktası vardır; belirli bir veri türü için takas. XOR takas gibi "Püf Noktaları" derleyicinin ne yapmaya çalıştığınızı görmesini zorlaştırır ve böylece bu tür optimizasyonları daha az uygulayabilmesini sağlar.

İkinci noktaya, eklenen karmaşıklık için ne kazanıyorsunuz? XOR yaklaşımını daha hızlı ölçüp bulsanız bile, bunun daha az net bir yaklaşımı haklı çıkarmak için yeterli bir etkisi var mı? Nereden biliyorsunuz?

Son olarak, platformunuz / diliniz için standart bir takas işlevi olup olmadığına bakmalısınız - örneğin C ++ STL, derleyici / platformunuz için oldukça optimize edilmiş bir şablon takas işlevi sağlar.


2

Meslektaşım bunun, üniversitede otomatik sistemler programcısı için çalışmakta olduğu bir temel numara olduğunu bildirdi. Bu tür sistemlerin çoğu sınırlı kaynaklara sahip gömülüdür ve geçici değeri korumak için ücretsiz bir sicile sahip olmayabilirler; Bu durumda, bu tür zorlu alışveriş (veya toplama ve çıkarma ile analog) hayati önem kazanıyor, bu yüzden hala kullanılıyor.

Ancak, bu iki konumun aynı olamayacağına dikkat etmek gerekir, çünkü ikinci durumda etkin bir şekilde her iki değeri de sıfırlayacaktır. Bu nedenle, genellikle bir sicil ve hafıza yeri değişimi gibi açık durumlar ile sınırlıdır.

X86 ile xchg ve cmpxchg komutları çoğu durumda ihtiyacı karşılar, ancak RISC'ler genellikle bunlarla kaplı değildir (Sparc hariç).

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.