Neden modern işlemcilerde bit-bilge işlemler kadar hızlı bir şekilde eklenebilir?


72

Bit işlemlerinin modern işlemcilerde çok hızlı olduğunu biliyorum, çünkü paralel olarak 32 veya 64 bit hızında çalışabilirler, bu yüzden bit işlemlerinin sadece bir saat sürmesi gerekir. Bununla birlikte, ekleme, en az bir ve muhtemelen bir düzine bit işlemli işlemden oluşan karmaşık bir işlemdir, bu yüzden doğal olarak 3-4 kat daha yavaş olacağını düşündüm. Basit bir kıyaslamadan sonra, eklemenin bit işlemlerinin (XOR, OR, vs.) olduğu kadar hızlı olduğunu görünce şaşırdım. Birisi buna ışık tutabilir mi?




1
Evet, testlerimde çarpma oldukça hızlıydı. Bölünme işleminden yalnızca 2 kat daha yavaştı, bölme 30x (!) Kat daha yavaştı.
SoloNasus

Son teknoloji paralel ön ek ağacı ekleyicilerine genel bakış: David Harris'in Paralel Ön Ek Ağlarının Taksonomisi: pages.hmc.edu/harris/research/taxonomy.pdf
Franki

Daha ayrıntılı: Doktora Jun Chen'in doktora tezi "İkili ve modulo için paralel önek yapıları {2n − 1, 2n, 2n + 1} ekleyiciler" digital.library.okstate.edu/etd/Chen_okstate_0664D_10070.pdf
Franki,

Yanıtlar:


104

Ekleme hızlıdır, çünkü CPU tasarımcıları hızlı hale getirmek için gereken devreyi koyarlar. Bitsel işlemlerden çok daha fazla geçit alır, ancak CPU tasarımcılarının buna değer olduğuna karar vermeleri sıktır. Bkz. Https://en.wikipedia.org/wiki/Adder_(electronics) .

Her ikisi de, tek bir CPU döngüsü içinde yürütülecek kadar hızlı yapılabilir. Eşit derecede hızlı değillerdir - ekleme işlemi bitsel bir işlemden daha fazla kapı ve gecikme süresi gerektirir - ancak bir işlemcinin bir saat döngüsünde yapabileceği kadar hızlıdır. Talimat kod çözme ve kontrol mantığı için talimat başına bir gecikme süresi vardır ve bunun gecikme süresi, bitli bir işlem yapmak için gecikme süresinden önemli ölçüde daha büyüktür, bu nedenle ikisi arasındaki fark, bu ek yük tarafından azaltılır. AProgrammer'in cevabı ve Paul92'nin cevabı bu etkileri iyi açıklıyor.


Yorumlar uzun tartışmalar için değildir; bu konuşma sohbete taşındı .
DW

38

Birkaç yönü var.

  • Bitsel işlemin göreceli maliyeti ve ekleme. Saf olmayan bir toplayıcı, kelimenin genişliğine doğrusal olarak bağlı olan bir geçit derinliğine sahip olacaktır. Derinliği azaltan kapılar açısından daha maliyetli olan alternatif yaklaşımlar vardır (IIRC, derinlik logaritmik olarak kelimenin genişliğine bağlıdır). Diğerleri bu tür teknikler için referanslar verdi, ben sadece farkın, gecikmelere neden olan kontrol mantığına olan ihtiyacı nedeniyle sadece operasyonun maliyetini göz önünde bulundurarak göründüğünden daha az önemli olduğunu belirteceğim.

  • O zaman işlemcilerin genellikle saatli olduğu gerçeği var (bazı araştırmaların veya özel amaçlı saatsiz tasarımların farkındayım, ancak bazılarının ticari olarak temin edilebildiğinden bile emin değilim). Bu, bir işlemin hızı ne olursa olsun, saat döngüsünün tamsayı olarak alınacağı anlamına gelir.

  • Son olarak, mikro mimari düşünceler var: Ne istediğinizi ölçtüğünüzden emin misiniz? Günümüzde, işlemciler sıradışı uygulama ve başka herhangi bir işlemle boru hattı, çoklu skalar olma eğilimindedir. Bu, aynı anda çeşitli tamamlanma aşamalarında birçok talimatı uygulayabilecekleri anlamına gelir. Bir işlemin diğerinden daha fazla zaman aldığını ölçerek göstermek istiyorsanız, hedefleri bu farkı gizlemek olduğu için bu yönü göz önünde bulundurmalısınız. Bağımsız veri kullanırken ek ve bitsel işlemler için aynı verime sahip olabilirsiniz, ancak işlemler arasında gecikmenin veya bağımlılıkların bir ölçüsü de gösterilebilir. Ayrıca, ölçütünüzün darboğazının örneğin hafıza erişiminde değil, uygulamada olduğundan emin olmalısınız.


6
+1. Evet, çoğu işlemci saatlidir , ancak birkaç saatsiz CPU ticari olarak temin edilebilir.
David Cary

2
Bir başka olasılık, bir işlemcinin bir 64-bitlik bir kayıt cihazını bir 16-bitlik parça ve üç 17-bitlik parça olarak saklayabilmesidir; Bitsel bir işlem veya bir mağaza tarafından takip edilen bir ilave, taşımayı ilerletmek için 1-2 ilave döngü gerektirebilir, ancak bunu başka bir ekleme tarafından takip edilen bir ekleme gerektirmez. Ayrıca, "mağaza" durumunda, fazladan çoğalma süresi mağazanın performansını geciktirebilir, ancak kodun bunun için "beklemesi" gerekmeyecektir.
supercat

3
@supercat Pentium 4, böyle bir şey yaptı; çift hızlı (işlemcinin geri kalanına göre) ALU, düşük 16 veya 32 bit, üst yarı bitlerden önce yarım döngü sonraki bir işlem için hazır olacak.
Jeffrey Bosboom

2
ne istediğini ölçmek istediğinden emin misin? Bu durumda OP'nin ölçümlerden çıkardığı sonuç CPU'ların büyük çoğunluğu için doğru olur. Ekleme o kadar yaygındır ki, süperskalar CPU'lar tüm yürütme bağlantı noktalarına birimler ekler ve boolean'lar uygulaması da (transistör sayımında) tüm bağlantı noktalarında da bulunacak kadar ucuzdur. Öyleyse, eklentiler ve boolean'lar neredeyse her zaman aynı verime sahip (örneğin Intel Haswell'de saat başına 4).
Peter Cordes

2
SIMD tamsayı ekleme işlemi, genellikle aynı gecikmeye sahip olmalarına rağmen, SIMD boolean'ından daha düşük verimdir. PentiumII’den Broadwell’e kadar Intel CPU’lar sadece vektör int (örneğin paddw) saat başına 2 hızında, ancak pandsaat başına 3'te boolean (gibi ) çalıştırabilir. (Skylake, her üç vektör yürütme portuna bir vektör toplayıcı koyar.)
Peter Cordes

24

CPU'lar döngü halinde çalışır. Her döngüde bir şey olur. Genellikle, bir komutun yürütülmesi için daha fazla döngü gerekir, ancak aynı anda birden fazla komut farklı durumlarda yürütülür.

Örneğin, basit bir işlemcinin her komut için 3 adımı olabilir: getir, çalıştır ve sakla. Herhangi bir zamanda, 3 komut işleniyor: biri getiriliyor, biri gerçekleştiriliyor ve biri sonuçlarını kaydediyor. Buna boru hattı denir ve bu örnekte 3 aşama vardır. Modern işlemciler 15'ten fazla aşamada boru hatlarına sahiptir. Bununla birlikte, ekleme, aritmetik işlemlerin çoğunun yanı sıra, genellikle tek bir aşamada gerçekleştirilir (ALU tarafından 2 sayı ekleme işleminden bahsediyorum, talimatın kendisiyle değil - işlemci mimarisine bağlı olarak, talimat gerekebilir) bellekten argüman almak, koşullu yapmak, sonuçları belleğe kaydetmek için daha fazla döngü).

Bir döngünün süresi en uzun kritik yol ile belirlenir. Temel olarak, boru hattının bir aşamasının tamamlanması için gereken en uzun süredir. CPU'yu daha hızlı yapmak istiyorsanız, kritik yolu optimize etmeniz gerekir. Kritik yolun azaltılması mümkün değilse, boru hattının 2 aşamasına bölünebilir ve artık CPU'nuzu neredeyse iki kat sıklıkta saat geçirebilirsiniz (bunu yapmanızı önleyen başka bir kritik yol olmadığı varsayılarak) ). Ancak bu bir ek yük ile birlikte gelir: boru hattının aşamaları arasına bir kayıt koymanız gerekir. Bu, gerçekten 2 kat hız kazanamadığınız anlamına gelir (kayıtcının verileri saklamak için zamana ihtiyacı vardır) ve tüm tasarımı karmaşık hale getirdiniz.

Ekleme yapmak için zaten oldukça verimli yöntemler vardır (örneğin, göz alıcı ekleyiciler taşımak) ve ek, işlemci hızı için kritik bir yol değildir, bu nedenle birden fazla döngüye ayırmanın bir anlamı yoktur.

Ayrıca, sizin için karmaşık görünse de, donanımda işler çok hızlı bir şekilde paralel yapılabilir.


3
Daha uzun boru hatlarından gelen büyük masraf, dal yanlışlığından kurtulmak için daha fazla döngüdür! Transistörlerin aşamalar arasında verileri tamponlamak için harcaması bugünlerde çok küçük. Basit bir boru hattı işlemcili işlemcinin bile, yürürlükteki komutların önüne geçmesi / kodu çözmesi gerekir. Eğer CPU bir dalın öngördüğünden (veya başka bir yanlış spekülasyondan) farklı bir yoldan gittiği için ön uç yanlış kod üzerinde çalışıyorsa, bu işi atmak ve doğru talimattan başlamak zorunda kalır. Uçuşta birçok insn içerebilecek üst düzey sıra dışı CPU'larla işler daha da kötüye gidiyor.
Peter Cordes

12

İşlemciler saatlidir, bu nedenle bazı talimatlar diğerlerinden daha hızlı bir şekilde yapılıyor olsa bile, aynı sayıda döngüyü alabilir.

Muhtemelen, kayıtlar ve yürütme birimleri arasında veri taşımak için gereken devrenin, ilave cihazlardan çok daha karmaşık olduğunu göreceksiniz.

Basit MOV (kayıt yaptırmak için) komutunun bitsel mantıktan daha az hesaplama yaptığını, ancak MOV ve ADD'nin genellikle bir döngü aldığını unutmayın. Eğer MOV iki kat daha hızlı yapılabilseydi, CPU'lar iki kat daha hızlı saatlere takılır ve ADD'ler iki devir olurlardı.


Yorumlar uzun tartışmalar için değildir; bu konuşma sohbete taşındı .
Gilles

1
Tartışmanın özeti: bazı sıra dışı CPU'lar MOV'ı özel olarak sıfır gecikmeyle, register-ad yeniden adlandırma işlemiyle özel olarak ele alır. Bkz. X86'nın MOV'u gerçekten “özgür” olabilir mi? Bunu neden yeniden üretemiyorum? MOV'un maliyetinin tam olarak ne olduğunu.
Peter Cordes

12

Toplama kadar önemli olup değil bir taşıma bit, 64-bit toplayıcı boyunca dalgalanacak için beklemek zorunda: bu terim bir olan carry lookahead toplayıcı ve onlar temelde yukarı 8 bit CPU (ve onların ALU) ve bir parçasıdır. Aslında, modern işlemciler ya tam çarpma için çok daha fazla yürütme süresine ihtiyaç duymazlar: taşıma-bakma kafası aslında bir işlemci tasarımcının araç kutusunda gerçekten eski (ve nispeten uygun fiyatlı) bir araçtır.


Tamsayılı çarpma, kesinlikle x86'daki ADD'den daha yüksek gecikme süresi ve daha düşük verimdir. Ancak hızlı bir çarpan inşa etmek için ne kadar ekleyici gerektiğine inanmak inanılmaz derecede hızlı: örn. Nehalem’den beri Intel ve Ryzen’den beri AMD, 8/16/32/64-bit skaler tamsayı çarpımı 1 devir başına bir, 3 devir gecikme süresi (bir adet tamamen borulanmış yürütme ünitesi). Bu, saat başına 3 veya 4 ADD verimi ile karşılaştırıldığında berbat, ancak Intel Pentium P5'teki 9 döngü IMUL gecikme süresi ile karşılaştırıldığında şaşırtıcı. SIMD için her şey benzer: vector-int multiply, gecikmeden daha düşük gecikme süresi ve daha hızlı sonuç veriyor ancak yine de hızlı.
Peter Cordes

Bu yüzden evet, çarptıkları şu anda olduğundan çok diğer talimatlara göre daha pahalıydı. 2 talimattan daha fazla maliyetten kaçınmak genellikle değmez ve bazen 2-talimat yerine bile değmez (örneğin bir shift + add leatalimatı ile).
Peter Cordes

9

Bitsel bir işlemden daha fazla döngü alan bir işlemci bulmakta zorlanacağınızı düşünüyorum. Kısmen, çoğu işlemcinin sadece program sayacını artırmak için her bir öğretim döngüsü için en az bir ekleme yapması gerektiği için. Sadece bitsel işlemler o kadar da kullanışlı değil.

(Talimat döngüsü, saat döngüsü değil - örneğin 6502, boru hattı olmadığından ve komut önbelleği olmadığından, komut başına en az iki saat döngüsü alır)

Eksik olabileceğiniz gerçek konsept kritik yoldur : bir yonganın içinde, bir döngü içinde gerçekleştirilebilecek en uzun işlem donanım seviyesinde çipin ne kadar hızlı saatlenebileceğini belirler.

Bunun istisnası, (nadiren kullanılan ve neredeyse hiç ticarileşmeyen) asenkron mantıktır, bu mantıksal yayılma zamanına, cihaz sıcaklığına vb. Bağlı olarak gerçekten farklı hızlarda uygulanır.


Kullanıcı tarafından kontrol edilebilir bitsel işlemler değildir, ancak 8086'daki bazı talimatlar (örn. Kesme bayrağını temizleme ) bir tamsayı ilavesinden daha az döngü aldı. Daha da soyut olarak, tüm talimatların tek bir kelime boyutunda olduğu bir RISC sistemi, PC için genel amaçlı bir toplayıcıdan çok daha hızlı bir devre olacak basit bir ikili sayıcı kullanabilir.
Mark

Program sayacına eklenmesi, aritmetik eklemeye kıyasla çok basit olma eğilimindedir, çünkü işlenenlerden biri küçüktür (bir komut boyutu veya boyut sınırlaması olan göreceli bir atlama kayması)
Ben Voigt

6502 boru hattına bağlandı - önceki komutun son döngüsü sırasında sonraki komutun ilk baytını okudu. Aksi halde, alma / kod çözme / yürütme en az üç döngü olacaktı.
gnasher729

8

Geçit seviyesinde, ilave yapmak için daha fazla iş gerektirdiği ve dolayısıyla daha uzun sürdüğü konusunda haklısınız. Ancak, bu maliyet önemli değil, önemsizdir.

Modern işlemciler saatlidir. Bu saat hızının katları dışında hiçbir şeyden talimat alamazsınız. Saat hızları daha yüksekse, bitsel işlemlerin hızını en üst düzeye çıkarmak için, ek olarak en az 2 döngü harcamanız gerekir. Bu sürenin büyük kısmı beklemeye harcanacaktı çünkü zamanın tam 2 döngüsüne gerçekten ihtiyacınız yoktu. Sadece 1.1'e ihtiyacın vardı (veya onun gibi bir sayı). Şimdi çipiniz piyasadaki herkesten daha yavaş ekliyor.

Daha da kötüsü, sadece bitsel işlemleri ekleme veya yapma eylemi, bir döngü sırasında olanların sadece küçük bir kısmıdır. Bir döngü içinde talimatları alıp çözebilmelisiniz. Bir döngü içinde önbellek işlemlerini yapabilmeniz gerekir. Basit ekleme veya bit yönünde işlemle aynı zaman ölçeğinde birçok başka şey oluyor.

Çözüm, elbette, bu görevleri bitsel bir işlemle tanımlanan minik çevrim süresine uyan minik parçalara ayırarak, çok derin bir boru hattı geliştirmek. Pentium 4, bu derin boru hattı terimlerinde düşünmenin sınırlarını meşhur etti. Her türlü sorun ortaya çıkıyor. Özellikle dallanma çok zorlaşır, çünkü hangi dalın alınacağını belirleyen verilere sahip olduğunuzda boru hattını yıkamanız gerekir.


7

Modern işlemciler saatlidir: Her işlem bazı integral saat döngüleri alır. İşlemcinin tasarımcıları bir saat döngüsünün uzunluğunu belirler. Burada iki husus var: Bir tanesi, örneğin tek bir NAND geçidinin gecikmesi olarak ölçülen donanımın hızı. Bu, kullanılan teknolojiye ve hız ve güç kullanımı gibi değişimlere bağlıdır. İşlemci tasarımından bağımsızdır. İkincisi, tasarımcılar bir saat döngüsünün uzunluğunun n'nin 10 veya 30 olabileceği tek bir NAND geçidinin n gecikmesine eşit olduğuna karar verir.

Bu seçenek n, bir döngüde ne kadar karmaşık işlemlerin gerçekleştirilebileceğini sınırlar. 16'da yapılabilecek ancak 15 NAND gecikmesinde gerçekleştirilemeyecek işlemler yapılacaktır. Bu nedenle n = 16'nın seçilmesi, böyle bir işlemin bir döngüde yapılabileceği, n = 15'in seçilemeyeceği anlamına gelir.

Tasarımcılar neyi seçecek, böylece birçok önemli işlem bir veya iki ya da üç döngü halinde gerçekleştirilebilir. n yerel olarak en uygun şekilde seçilecektir: n'yi n-1 ile değiştirirseniz, çoğu işlem biraz daha hızlı olur, ancak bazıları (gerçekten tam n NAND gecikmelerine ihtiyaç duyanlar) yavaşlar. Eğer az sayıda işlem yavaşlarsa, genel program yürütme ortalama olarak daha hızlı olursa, n-1'i seçmiş olursunuz. Ayrıca n + 1 seçmiş olabilirsiniz. Bu işlemlerin çoğunu biraz daha yavaşlatır, ancak n gecikmelerde yapılamayan ancak n + 1 gecikmelerde yapabileceğiniz birçok işleminiz varsa işlemciyi genel olarak daha hızlı hale getirir.

Şimdi sorunuz: Toplama ve çıkarma işlemi o kadar yaygındır ki, bunları tek bir döngüde yürütmek isteyebilirsiniz. Sonuç olarak, AND VEYA VEYA'nın daha hızlı çalışabilmesi önemli değil: Hala bir döngüye ihtiyaçları var. Elbette "hesaplama" VE, VEYA, ünitesinin başparmaklarını gizlemek için çok zamanı var, ama bu yardım edilemez.

NAND gecikmeleri dahilinde bir işlemin yapılıp yapılmayacağının sadece olmadığını unutmayın: Örneğin ek bir parça biraz akıllıca daha hızlı, daha akıllıca daha hızlı, olağanüstü donanımlara yatırım yaparak biraz daha hızlı yapılabilir. ve son olarak, bir işlemci çok hızlı, çok pahalı ve biraz daha yavaş ve daha ucuz devrelerin bir karışımına sahip olabilir, bu yüzden bir işlemi daha fazla para harcayarak yeterince hızlı bir şekilde yapma olasılığı vardır.

Şimdi olabilir saat hızı o kadar yüksek hale / yani sadece basit bit işlemleri tek döngüde çalıştırmak olduğunu kısa ve iki veya daha fazla her şeyin döngüsü. Bu büyük olasılıkla işlemciyi yavaşlatır. İki döngü alan işlemler için, eksik bir komutu bir döngüden diğerine taşımak için genellikle ek yük vardır, bu nedenle iki döngü yürütme için iki kat daha fazla zamanınız olduğu anlamına gelmez. Dolayısıyla, iki döngüde ekleme yapmak için saat hızını iki katına çıkaramazsınız.


6

Mevcut cevaplarınızda açıkça belirtilmeyen bazı şeyleri düzelteyim:

Bitsel işlemlerin modern işlemcilerde çok hızlı olduğunu biliyorum, çünkü paralel olarak 32 veya 64 bit üzerinde çalışabilirler,

Bu doğru. Bir CPU'yu genellikle "XX" bit olarak (her zaman değil) etiketlemek, genel yapılarının çoğunun (kayıt genişlikleri, adreslenebilir RAM vb.) Boyutunda XX bit (genellikle "+/- 1" veya somesuch) olduğu anlamına gelir. Ancak, sorunuzla ilgili olarak, 32 bit veya 64 bitlik bir işlemcinin 32 veya 64 bitlik herhangi bir temel bit işleminin sabit sürede yapılacağını güvenle varsayabilirsiniz.

bu yüzden bitsel işlemler sadece bir saat döngüsü alır.

Bu sonuç mutlaka böyle değil. Özellikle zengin komut setleri olan (google CISC ve RISC) CPU'lar basit komutlar için bile birden fazla döngü alabilir. Serpiştirme ile, basit komutlar bile 3 saat ile getirme-yürütme-deposuna dönüşebilir (örnek olarak).

Ancak eklenti karmaşık bir işlemdir

Hayır, tamsayı ekleme basit bir işlemdir; de çıkarma. Ek donanımları tam donanımda uygulamak çok kolaydır ve eşyalarını temel bit işlemleri gibi anında yaparlar.

bu en az bir ve muhtemelen bir düzine kadar bit işlemden ibarettir, bu yüzden doğal olarak 3-4 kat daha yavaş olacağını düşündüm.

Transistörlerin 3-4 katı kadar sürecek, ancak ihmal edilebilir olan büyük resimle karşılaştırıldığında.

Basit bir kıyaslamadan sonra eklemenin bitsel işlemlerin (XOR, VEYA VEYA) olduğu kadar hızlı olduğunu görünce şaşırdım. Birisi buna ışık tutabilir mi?

Evet: tamsayı ilavesi olan bir bit düzeyinde işlem (diğerlerine göre biraz daha fazla bit ile, ama yine de). Aşamalarda herhangi bir şey yapmaya gerek yoktur, karmaşık algoritmalara, saatlere veya başka herhangi bir şeye ihtiyaç yoktur.

CPU mimarinizden daha fazla bit eklemek istiyorsanız, bunu aşama aşama yapmak zorunda kalmanın cezasını çekeceksiniz. Ancak bu başka bir karmaşıklık düzeyindedir (programlama dili seviyesi, montaj / makine kodu seviyesi değil). Bu, geçmişte (veya bugün küçük gömülü işlemcilerde) yaygın bir sorundu. PC'ler vb. İçin, 32 veya 64 bit, bunun en yaygın veri türlerinin tartışma noktası olmaya başlaması için yeterlidir.


O (N) 'den O' ya kadar zaman maliyetinin düşürülmesinin (sqrt (N)) düşürülmesi gereken transistör sayısını veya yönlendirme karmaşıklığını önemli ölçüde arttırmadığını not etmek ilginçtir (her aşamada bir telin aşağıdan içeri gizlice girmesine izin vermesi gerekir) ve sqrt (N) fazladan birleştirme aşamaları olması gerekir, zaman maliyeti O (lgN) transistörlerin maliyeti ile O (lgN) 'ye düşürülebilir, ancak çoğu durumda 64- örneğin 8 bitlik bit eklemesi (sqrtN iletimi kullanarak) bit birleştirme mantığı ile birleştirildi, 64 bitlik birleştirme ile altı katmanın birleştirilmesiyle birleştirildi
supercat

Evet, ekleyiciler oldukça basittir. Gerçekten etkileyici olan, tamamen boru hattı olan 3 zamanlı gecikmeli 64 bit tam sayı çarpanı olan modern x86 işlemcilerdir . (örneğin imul rax, rcx, Intel Sandybridge ailesi ve AMD Ryzen'de 3c gecikme süresi ve her 1c verimlilikte bir). 64 bit tam çarpma bile (rdx: rax'te 128 bitlik sonuç üretiliyor) aynı gecikme ve verim değerine sahip, ancak 2 adet (farklı bağlantı noktalarında paralel olarak çalışan) olarak uygulandı. ( Talimat tabloları ve mükemmel bir microarch kılavuzu için bkz. Agner.org/optimize ).
Peter Cordes

[bir araya getirme], başka bir karmaşıklık düzeyindedir (programlama dili seviyesi, montaj / makine kodu seviyesi değil programlama dili . Dile göre değişir. 16 bitlik bir işlemciyi hedefleyen AC derleyici, derleme yaparken sizin için ekleme / adlandırma vermelidir) İki uint32_tdeğerin eklenmesi Bugün 32-bit hedeflerde int64_t için hala geçerli AVR bir 8-bit RISC mikrokontrolcüsüdür, bu yüzden 32-bit tamsayılar 4 komut gerektirir: godbolt.org/g/wre0fM
Peter Cordes

Evet, @PeterCordes, demek istediğim bu, cümleyi biraz netleştirdim.
AnoE
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.