Modern CPU'lar ile çevrim sayımı (örn. ARM)


14

Birçok uygulamada, komut yürütmesi beklenen giriş uyaranlarıyla bilinen bir zamanlama ilişkisi olan bir CPU, ilişki bilinmiyorsa çok daha hızlı bir CPU gerektiren görevleri işleyebilir. Örneğin, video oluşturmak için PSOC kullandığım bir projede, her 16 CPU saatinde bir bayt video verisi çıkışı için kod kullandım. SPI cihazının hazır olup olmadığının test edilmesi ve eğer değilse IIRC'nin 13 saat alacağı ve çıkış verisine yük ve depolamanın 11 alacağı test edildiğinden, cihazı baytlar arasında hazır olup olmadığını test etmenin bir yolu yoktu; Bunun yerine, işlemcinin ilkinden sonra her bayt için 16 döngünün kodunu tam olarak yürütmesini sağladım (gerçek bir dizinlenmiş yük, bir sahte dizin yükü ve bir mağaza kullandığımı düşünüyorum). Her satırın ilk SPI yazımı videonun başlamasından önce oldu, ve sonraki her yazma işlemi için, yazma işleminin arabellek aşımı veya az çalışması olmadan meydana gelebileceği 16-döngü bir pencere vardı. Dallanma döngüsü bir 13 döngü belirsizlik penceresi üretti, ancak öngörülebilir 16 döngü yürütme, sonraki tüm baytlar için belirsizliğin aynı 13 döngü penceresine uyacağı anlamına geliyordu (bu da yazmanın kabul edilebilir olduğu 16 döngü penceresine sığacak) ) meydana gelir.

Daha eski CPU'lar için, talimat zamanlama bilgileri açık, kullanılabilir ve açıktı. Daha yeni ARM'ler için, zamanlama bilgisi çok daha belirsiz görünüyor. Kod flash yürütülürken, önbellekleme davranışı tahmin etmek çok daha zor hale anlayabiliyorum, bu yüzden herhangi bir döngü sayılan kod RAM yürütülmelidir beklenebilir. RAM'den kod çalıştırırken bile, özellikler biraz belirsiz görünüyor. Çevrim sayımlı kod kullanımı hala iyi bir fikir midir? Öyleyse, güvenilir bir şekilde çalışması için en iyi teknikler nelerdir? Bir çip satıcısının, belirli durumlarda belirli talimatların yürütülmesini devre dışı bırakan bir "yeni geliştirilmiş" çipte sessizce kaymayacağını ne kadar güvenli bir şekilde varsayabiliriz?

Aşağıdaki döngünün bir kelime sınırında başladığı varsayılarak, spesifikasyonlara göre ne kadar süreceği kesin olarak nasıl belirlenir (Cortex-M3'ü sıfır bekleme durum hafızası ile varsayalım; sistem hakkında başka hiçbir şey bu örnek için önemli olmamalıdır).

myloop:
  mov r0, r0; Daha fazla talimatın önceden getirilmesine izin vermek için kısa basit talimatlar
  mov r0, r0; Daha fazla talimatın önceden getirilmesine izin vermek için kısa basit talimatlar
  mov r0, r0; Daha fazla talimatın önceden getirilmesine izin vermek için kısa basit talimatlar
  mov r0, r0; Daha fazla talimatın önceden getirilmesine izin vermek için kısa basit talimatlar
  mov r0, r0; Daha fazla talimatın önceden getirilmesine izin vermek için kısa basit talimatlar
  mov r0, r0; Daha fazla talimatın önceden getirilmesine izin vermek için kısa basit talimatlar
  r2, r1, # 0x12000000 ekler; 2 kelimelik talimat
  ; Muhtemelen farklı işlenenlerle aşağıdakileri tekrarlayın
  ; Bir taşıma gerçekleşene kadar değer eklemeye devam edecek
  ITCC
  addscc r2, r2, # 0x12000000; 2 kelimelik talimatlar, artı itcc için ekstra "kelime"
  ITCC
  addscc r2, r2, # 0x12000000; 2 kelimelik talimatlar, artı itcc için ekstra "kelime"
  ITCC
  addscc r2, r2, # 0x12000000; 2 kelimelik talimatlar, artı itcc için ekstra "kelime"
  ITCC
  addscc r2, r2, # 0x12000000; 2 kelimelik talimatlar, artı itcc için ekstra "kelime"
; ... vb, daha koşullu iki kelimelik talimatlarla
  alt r8, r8, # 1
  bpl myloop

İlk altı talimatın yürütülmesi sırasında, çekirdeğin üç kelimeyi yürütecek altı kelimeyi getirecek zamanı olacaktır, bu nedenle önceden getirilmiş üç taneye kadar olabilir. Sonraki talimatların her biri üç kelimeden oluşur, bu nedenle çekirdeğin talimatları yürütülmekte olduğu kadar hızlı getirmesi mümkün olmaz. Bazı "bu" talimatların bir döngü alacağını umuyorum, ama hangilerini tahmin edeceğimi bilmiyorum.

ARM'nin "it" talimat zamanlamasının belirleyici olacağı belirli koşulları belirleyebilmesi iyi olurdu (örneğin, bekleme durumları veya kod-veri yolu çekişmesi yoksa ve önceki iki talimat 16 bit kayıt talimatları vb. İse) ama böyle bir özellik görmedim.

Örnek uygulama

Birinin 480P'de komponent video çıkışı oluşturmak için Atari 2600 için bir anakart tasarlamaya çalıştığını varsayalım. 2600, 3.579MHz piksel saatine ve 1.19MHz CPU saatine (nokta saati / 3) sahiptir. 480P komponent video için, her bir hattın 7.158MHz nokta saat çıkışı anlamına gelen iki çıkışı olmalıdır. Atari'nin video yongası (TIA), 3 bit luma sinyali artı yaklaşık 18ns çözünürlüğe sahip bir faz sinyali kullanarak 128 renkten birini çıkardığı için, yalnızca çıktılara bakarak rengi doğru bir şekilde belirlemek zor olacaktır. Daha iyi bir yaklaşım, renk kayıtlarına yazma işlemlerini durdurmak, yazılan değerleri gözlemlemek ve her kaydı, kayıt numarasına karşılık gelen TIA parlaklık değerlerinde beslemek olacaktır.

Tüm bunlar bir FPGA ile yapılabilir, ancak bazı oldukça hızlı ARM cihazları, gerekli tamponlamayı işlemek için yeterli RAM'e sahip bir FPGA'dan çok daha ucuza sahip olabilir (evet, bu tür bir şeyin üretilebileceğini biliyorum. t gerçek bir faktör). Ancak, ARM'nin gelen saat sinyalini izlemesini istemek, gerekli CPU hızını önemli ölçüde artıracaktır. Öngörülebilir döngü sayıları işleri daha temiz hale getirebilir.

Nispeten basit bir tasarım yaklaşımı, bir CPLD'nin CPU ve TIA'yı izlemesi ve 13 bit RGB + senkronizasyon sinyali üretmesi ve daha sonra ARM DMA'nın bir porttan 16 bit değerleri alması ve bunları uygun zamanlamayla yazmasıdır. Bununla birlikte, ucuz bir ARM'nin her şeyi yapıp yapamayacağını görmek ilginç bir tasarım zorluğu olurdu. CPU döngüsü sayıları üzerindeki etkileri tahmin edilebilirse (özellikle bellek veri yolu başka bir şekilde boşta olduğunda döngülerde DMA döngüleri meydana gelebiliyorsa), ancak sürecin bir noktasında DMA, hepsi bir arada bir yaklaşımın yararlı bir yönü olabilir. ARM masa araması ve otobüs izleme işlevlerini yerine getirmek zorundaydı. Karartma aralıkları sırasında renk kayıtlarının yazıldığı birçok video mimarisinin aksine, Atari 2600'ün bir karenin görüntülenen bir bölümü sırasında sık sık renk kayıtlarına yazdığını,

Belki de en iyi yaklaşım, renk yazmalarını tanımlamak ve renk kayıtlarının alt bitlerini uygun değerlere zorlamak için birkaç ayrık mantık yongaları kullanmak ve daha sonra gelen CPU veri yolu ve TIA çıkış verilerini örneklemek için iki DMA kanalı kullanmak ve çıkış verilerini oluşturmak için üçüncü bir DMA kanalı. CPU daha sonra her tarama hattı için her iki kaynaktan gelen tüm verileri işlemek, gerekli çeviriyi yapmak ve çıktı için arabelleğe almakta serbesttir. Bağdaştırıcının görevlerinin "gerçek zamanlı" olarak gerçekleşmesi gereken tek yönü, COLUxx'a yazılan verilerin geçersiz kılınmasıdır ve bu iki ortak mantık yongalarının kullanılmasıyla halledilebilir.

Yanıtlar:


7

DMA'ya oy veriyorum. Cortex-M3 ve üstü için gerçekten esnektir - ve herhangi bir CPU döngüsünü harcamadan belirli bir yerden otomatik olarak veri almak ve belirtilen hızda veya bazı olaylarda çıkış yapmak gibi her türlü çılgın şeyi yapabilirsiniz. DMA çok daha güvenilirdir.

Ancak ayrıntıları anlamak oldukça zor olabilir.

Başka bir seçenek de, bu dar şeylerin donanım uygulamasıyla FPGA üzerindeki yumuşak çekirdeklerdir.


1
DMA fikrini seviyorum. Cortex M3 çekirdeğinin herhangi bir DMA'sı olduğunu düşünmüyorum - bu, bireysel üreticilerin cipslerinin bir işlevi ve hepsi farklı kullanıyor. Aslında oynadığım en az bir uygulama ile (STM32L152) irksome bulduğum bir şey, DMA veri çıkışı olduğunda bir pin strobe sahip olmak için herhangi bir yol bulamıyor olmasıdır. Hangi faktörlerin DMA zamanlamasını etkileyebileceği de açık değildir.
supercat

1
Her halükarda, hassas döngü vuruşu için düşündüğüm ilk uygulamalardan biri ile ilgili olarak, orijinal soruya daha fazla bilgi gönderdim. Ne düşündüğünü merak ediyorum. Döngüyü vurmayı düşündüğüm başka bir durum, ekran verilerini renkli bir LCD'ye patlatmak olurdu. Veriler RAM'de 8 bit renk kullanılarak arabelleğe alınır, ancak ekran 16 bit renklere ihtiyaç duyar. Verilerin çıktısını almayı düşündüğüm en hızlı yol, yazma çakmalarını oluşturmak için donanım kullanmak olurdu, bu yüzden CPU sadece verileri zaman aşımına uğratmak zorunda kalacaktı. 8-> 16 bit'i küçük bir arabelleğe çevirmek iyi olur mu ...
supercat

1
... ve sonra DMA'yı bunu aktaracak şekilde ayarlayın, yoksa en iyi yaklaşım hangisidir?
supercat

4

Zamanlama bilgisi mevcuttur, ancak belirttiğiniz gibi zaman zaman belirsiz olabilir. Cortex-M3 için Teknik Referans Kılavuzunun Bölüm 18.2 ve Tablo 18.1'inde birçok zamanlama bilgisi vardır , örneğin ( burada pdf ) ve bir alıntı:

18.2 alıntısı

maksimum zamanlama için koşulların bir listesini verir. Birçok talimatın zamanlaması, bazıları belirsizlikler bırakan dış faktörlere bağlıdır. Bu bölümden aşağıdaki alıntıda bulduğum belirsizliklerin her birini vurguladım:

[1] Şubeler talimat için bir döngü alır ve daha sonra hedef talimat için boru hattı yeniden yüklenir. Alınmayan dallar toplam 1 döngüdür. Anında alınan dallar normalde 1 döngü boru hattı yeniden yüklemesidir (toplam 2 döngü). Kayıt işlenenli alınan dallar normalde 2 döngü boru hattı yeniden yüklemesidir (toplam 3 döngü). Daha yavaş belleğe erişmenin yanı sıra, hizalanmamış 32 bit yönergelere ayrılırken ardışık düzen yeniden yüklemesi daha uzundur [Ne kadar uzun?]. Kod veriyoluna, daha yavaş bir sistemin [Ne kadar yavaş?] Önyüklemeye izin veren bir şube ipucu verilir . Bu , [Bu isteğe bağlı mı ?] Şubenin daha yavaş bellek için hedeflediği cezayı azaltabilir , ancak asla burada gösterilenden daha az olamaz.

[2] Genel olarak, yük deposu talimatları ilk erişim için iki döngü ve her ek erişim için bir devir alır. Acil ofsetleri olan mağazalar bir döngü alır.

[3] UMULL / SMULL / UMLAL / SMLAL , kaynak değerlerinin boyutuna bağlı olarak erken sonlandırma kullanır [Hangi boyutlar?]. Bunlar bir döngünün en kötü durum gecikmesi ile kesilebilir (terkedilmiş / yeniden başlatıldı). MLAL sürümleri dört ila yedi döngü ve MULL sürümleri üç ila beş döngü alır . MLAL için, imzalı sürüm imzasız olandan bir döngü daha uzundur.

[4] BT talimatları katlanabilir . [Ne zaman? Yorumlara bakınız.]

[5] DIV zamanlamaları temettü ve bölene bağlıdır . [MUL ile aynı problem] DIV, bir döngünün en kötü durum gecikmesi ile kesilebilir (terk edilmiş / yeniden başlatılır). Temettü ve bölen benzer olduğunda [Ne kadar benzer?], Bölünme hızla sona erer. Minimum süre, temettüden daha büyük bölen ve sıfır bölen için geçerlidir. Sıfır bölücü sıfır döndürür (hata değil), ancak bu durumu yakalamak için bir hata ayıklama tuzağı kullanılabilir. [MUL için verilen aralıklar nelerdir?]

[6] Uyku, talimat için bir döngü artı uygun olduğu kadar çok uyku döngüsüdür. WFE, etkinlik geçtiğinde yalnızca bir döngü kullanır. WFI girerken kesin olarak bir kesinti olmazsa, WFI normalde birden fazla döngüdür.

[7] ISB bir döngü alır (dal görevi görür). Veriler yazma arabelleğinde veya LSU'da beklemedikçe DMB ve DSB bir döngü alır. Bir engel sırasında bir kesinti olursa, terk edilir / yeniden başlatılır.

Tüm kullanım durumları için, "Bu komut bir döngüdür, bu talimat iki döngüdür, bu bir döngüdür ..." den daha basit olacaktır. Bazı kullanım durumlarında, herhangi bir belirsizlikle karşılaşmazsınız. Belirsizliklerle karşılaşırsanız şunu öneririm:

  1. Satıcınıza başvurun ve kullanım durumunuz için talimat zamanlamasının ne olduğunu sorun.
  2. Belirsiz davranışı belirlemek için test edin
  3. İşlemci revizyonlarını ve özellikle satıcı değişikliklerinden geçerken yeniden test edin.

Bu gereksinimler muhtemelen "Hayır, karşılaşılan zorluklar maliyete değmezse iyi bir fikir değildir" sorusunun yanıtını verir - ancak bunu zaten biliyordunuz.


1
Aşağıdakilerin belirsiz olduğunu düşünürdüm: "Daha yavaş belleğe erişmenin yanı sıra, hizalanmamış 32 bit komutlara dallandığında da boru hattı yeniden yüklemesi daha uzun", bir döngü ekleyip eklemediğini söylemiyor ve "BT talimatları katlanabilir" hangi koşullar altında olacağını veya olmayacağını belirtmezler.
supercat

1
"BT" zamanlaması özellikle rahatsız edici görünebilir, çünkü bu sık sık döngü sayımlı bir döngüde kullanılacak bir talimattır ve her zaman katlanamayacağından eminim. Biri her zaman zamanlamaya duyarlı bir döngünün başlangıcına dallarsa, döngüyü bir sözcük sınırında başlamaya zorlarsa, döngü içinde herhangi bir koşullu yük veya depodan kaçınır ve birinin hemen "BT" talimatı koymaz. yükleme veya kayıt güncelleme mağazasından sonra, "BT" zamanlamaları tutarlı olur, ancak spesifikasyon bunu netleştirmez.
supercat

1
Benim tahminim, BT'nin muhtemelen (doğrulukla) "Bekleme durumları veya kod-veri yolu çekişmesi olmadığında, (1) önceki talimatın erişmeyen 16 bitlik bir talimat olması durumunda BT katlanması garanti edilebilir. ve (2) ya bir sonraki talimat 16 bitlik bir talimattır ya da bir önceki talimat bir "hizalanmamış" dalın hedefi değildi. BT katlanması diğer belirtilmemiş durumlarda da meydana gelebilir. Böyle bir özellik, kodun belirtildiği gibi düzenlenmesini sağlayarak öngörülebilir IT talimatı zamanlaması olan programlar yazmanıza izin verecektir.
supercat

1
Vay canına, masanın altındaki uyarılarla boğuşmak yerine sadece basit en kötü durum sayımlarından geçtiğimi itiraf ediyorum. Güncellenmiş cevabım diğer bazı belirsizlikleri vurgulamaktadır.
Kevin Vermeer

1
Bir kişinin en kötü durum sayılarıyla ilgilendiği birçok durum vardır ve birinin en iyi durum sayılarıyla ilgilendiği adil bir sayı vardır (örneğin, bir SPI bağlantı noktası her 16 döngüde bir bayt üretebiliyorsa, her baytı oluşturmak 14 döngü alacaktır en iyi durumda ve hazır olup olmadığını kontrol etmek 5 döngü alacaktır, her baytın hazır olup olmadığını kontrol etmek hızı her 19 döngüde bir bayt ile sınırlar; en iyi durumda iki ek NOP ile körü körüne yazmak en iyi 16 döngüde bir bayt hızına izin verir ). Kesin zamanlamanın gerekli olduğu durumlar yaygın değildir, ancak ortaya çıkabilirler.
supercat

3

Bu sorunu çözmenin bir yolu, Parallax Pervane ve XMOS yongaları gibi deterministik veya öngörülebilir zamanlamalara sahip cihazları kullanmaktır:

http://www.parallaxsemiconductor.com/multicoreconcept

http://www.xmos.com/

Döngü sayımı, Pervane ile çok iyi çalışır (montaj dili kullanılmalıdır), XMOS cihazları çok güçlü bir yazılım yardımcı programına sahipken, XC programlama dilinde yazılmış uygulamalarla çalışan XMOS Zamanlama Analizörü:

https://www.xmos.com/download/public/XMOS-Timing-Analyzer-Whitepaper%281%29.pdf


1
Leon'un XMOS'ta hisseleri olduğunu düşünmeye başlıyorum ... ;-)
Federico Russo

1
Sadece fişlerini ve orada çalışan insanları seviyorum. Paralaks iyi ürünlerle güzel bir şirkettir.
Leon Heller

1
Evet, suç yok. Sadece XMOS'un bahsettiği tüm cevapların (bir tanesi hariç) sizden geldiğine dikkat çekiyor. Bir şey konusunda hevesli olmanın yanlış bir yanı yok.
Federico Russo

@Federico, @Leon - XMOS hakkında beni biraz endişelendiren şey tam olarak bu: neden dünyada sadece 1 kullanıcı var (en azından öyle görünüyor)? Eğer bu kadar güzelse, neden kasabanın konuşması değil? Hiç kimsenin bunun hakkında konuştuğunu duymadım, daha az kullan.
stevenvh

XMOS forumlarını deneyin: xcore.com
Leon Heller

2

Düşük seviyeli mikrodenetleyicilerden ve daha genel amaçlı bilgisayar işlemcilerinden uzaklaştıkça, döngü sayımı daha sorunlu hale gelir. Birincisi, kısmen sitenizin nedenlerinden ötürü, genellikle iyi belirlenmiş talimat zamanlamasına sahiptir. Ayrıca mimarileri oldukça basit olduğundan, talimat süreleri sabit ve bilinir.

Bunun iyi bir örneği çoğu Microchip PIC'tir. 10, 12, 16 ve 18 serileri çok iyi belgelenmiş ve öngörülebilir talimat zamanlamasına sahiptir. Bu, bu çiplerin amaçladığı küçük kontrol uygulamaları türünde yararlı bir özellik olabilir.

Ultra düşük maliyetten uzaklaştıkça ve tasarımcı daha egzotik bir mimariden daha yüksek hız elde etmek için biraz daha fazla yonga alanı harcayabildiğinden, öngörülebilirlikten de uzaklaşırsınız. Bunun en uç örnekleri olarak modern x86 varyantlarına bir göz atın. Sayma komut döngülerini neredeyse imkansız hale getiren çeşitli önbellek seviyeleri, belleğin vitualizasyonu, ileri alma getirme, boru hattı oluşturma ve daha fazlası vardır. Bu uygulamada, müşteri talimat zamanlaması öngörülebilirliği ile değil, yüksek hız ile ilgilendiği için önemli değildir.

Bu efekti daha yüksek Microchip modellerinde çalışırken bile görebilirsiniz. 24 bit çekirdek (24, 30 ve 33 serisi), kayıt veriyolu çekimleri olduğunda birkaç istisna dışında büyük ölçüde tahmin edilebilir talimat zamanlamasına sahiptir. Örneğin, bazı durumlarda, bir sonraki komut bir önceki komutta değeri değiştirilen bazı dolaylı adresleme modlarına sahip bir kayıt kullandığında makine bir durak ekler. Bu tür bir durak bir dsPIC'de olağandışıdır ve çoğu zaman onu görmezden gelebilirsiniz, ancak bu şeylerin size daha hızlı ve daha yetenekli bir işlemci vermeye çalışan tasarımcılardan dolayı nasıl sürüneceğini gösterir.

Yani temel cevap, bir işlemci seçtiğinizde bunun bir parçası. Küçük kontrol uygulamaları için küçük, ucuz, düşük güç ve öngörülebilir talimat zamanlaması ile bir şey seçebilirsiniz. Daha fazla işlem gücü talep ettikçe, mimari değişebilir, böylece öngörülebilir talimat zamanlamasından vazgeçmeniz gerekir. Neyse ki, daha yoğun bilgi işlem gerektiren ve genel amaçlı uygulamalara gittiğinizde bu daha az sorun teşkil ediyor, bu yüzden ödünleşmelerin makul derecede iyi çalıştığını düşünüyorum.


Genel olarak daha fazla hesaplama-yoğun olan uygulamaların mikroskobik zamanlamaya daha az duyarlı hale geldiğini kabul ediyorum, ancak birinin PIC-18'den biraz daha fazla işleme oomphine ihtiyaç duyabileceği, ancak öngörülebilirliğe ihtiyaç duyabileceği bazı senaryolar var. 16-bit PIC mimarileri gibi şeyleri ne ölçüde öğrenmeye çalışmam gerektiğini veya ARM'nin büyük olasılıkla yeterli olacağını anlamam gerektiğini merak ediyorum.
supercat

0

Evet, hala bir ARM'de bile yapabilirsiniz. Bir ARM'deki en büyük sorun, ARM'nin çekirdek değil cips satması ve çekirdek zamanlamanın bilinmesidir, ancak çip satıcısının etrafına sardığı şey satıcıdan satıcıya ve bazen de yonga ailesinden satıcı içinde başka bir şeye değişir. Bu nedenle, belirli bir satıcıdan belirli bir yonga oldukça belirleyici olabilir (örneğin önbellek kullanmazsanız), ancak bağlantı noktası zorlaşır. Burada 5 saat ve zamanlayıcıları kullanan 11 saatle uğraşırken zamanlayıcıyı örneklemek ve zaman aşımınızın süresinin dolup dolmadığını anlamak için gereken talimat sayısı kadar sorunludur. Geçmiş programlama deneyiminizin seslerinden, muhtemelen bir osiloskopla yaptığım gibi hata ayıklamak için bahse girmeye hazırım, böylece yonga üzerinde saat hızında sıkı bir döngü deneyebilir, spi veya i2c'ye veya herhangi bir dalga formuna bakabilirsiniz, veya nopsları kaldırın, döngü boyunca kaç kez değiştirin ve temel olarak ayarlayın. Herhangi bir platformda olduğu gibi, kesintilerin kullanılmaması, talimat uygulamasının deterministik doğasına büyük ölçüde yardımcı olur.

Hayır, gecikme / zamanlama işlemcinin saat hızına yaklaşırsa, bir PIC kadar basit değildir, ancak yine de oldukça yapılabilir. Bir dizi ARM tabanlı satıcı, saat hızını çarpmanıza ve 8 mhz'lik bir referanstan 60MHz diyelim. güç bütçesi) ve daha sonra bir zamanlayıcı kullanın ve başka şeyler yapmak için kendinize çok sayıda saat verin.

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.