@ vicatcu'nun cevabı oldukça kapsamlı. Dikkat edilmesi gereken bir diğer şey, CPU'nun program ve veri belleği de dahil olmak üzere G / Ç'ye erişirken bekleme durumlarına (durmuş CPU döngüleri) girebilmesidir .
Örneğin, bir TI F28335 DSP kullanıyoruz; RAM'in bazı alanları program ve veri belleği için 0-bekleme durumudur, bu nedenle RAM'de kod çalıştırdığınızda, komut başına 1 döngüde çalışır (1 döngüden fazla süren talimatlar hariç). Ancak FLASH bellekten (dahili EEPROM, daha fazla veya daha az) kod çalıştırdığınızda, tam 150MHz'de çalışamaz ve birkaç kat daha yavaştır.
Yüksek hızlı kesme koduyla ilgili olarak, bir dizi şey öğrenmelisiniz.
İlk olarak, derleyicinize çok aşina olun. Derleyici iyi bir iş çıkarıyorsa, çoğu şey için elle kodlanmış montajdan çok daha yavaş olmamalıdır. (burada "çok daha yavaş": 2 faktörü benim için uygun olurdu; 10 faktörü kabul edilemez olacaktır) Derleyici optimizasyon bayraklarını nasıl (ve ne zaman) kullanacağınızı ve arada bir bakmanız gerekir nasıl olduğunu görmek için derleyicinin çıktısında.
Kodu hızlandırmak için derleyicinin yapabileceği diğer bazı şeyler:
satır içi işlevleri kullanın (C'nin bunu destekleyip desteklemediğini veya yalnızca bir C ++ - ism olup olmadığını hatırlayamayın), hem küçük işlevler hem de yalnızca bir veya iki kez yürütülecek işlevler için. Dezavantajı, özellikle derleyici optimizasyonu açıksa satır içi işlevlerin hatalarını ayıklamak zordur. Ancak, özellikle "işlev" soyutlaması kod uygulaması yerine kavramsal tasarım amaçları içinse, gereksiz çağrı / dönüş dizilerini kurtarırlar.
Kendine özgü işlevlere sahip olup olmadığını görmek için derleyicinizin kılavuzuna bakın - bunlar doğrudan işlemcinin montaj talimatlarıyla eşleşen derleyiciye bağlı yerleşik işlevlerdir; bazı işlemciler, min / max / bit ters gibi faydalı şeyler yapan montaj talimatlarına sahiptir ve bunu yaparken zaman kazanabilirsiniz.
Sayısal hesaplama yapıyorsanız, matematik kitaplığı işlevlerini gereksiz yere çağırmamaya dikkat edin. Kodun y = (y+1) % 4
4 periyodu olan bir sayaç için olduğu gibi bir derleyici vardı, derleyicinin modulo 4'ü bitsel-AND olarak uygulamasını bekliyor. Bunun yerine matematik kütüphanesini çağırdı. Böylece y = (y+1) & 3
istediğimizi yapmak için yerini aldık.
Biraz dönen hackler sayfasına aşina olun . Bunlardan en az birini sık sık kullanacağınızı garanti ederim.
Kod yürütme süresini ölçmek için CPU'nuzun zamanlayıcı çevre birimlerini de kullanmalısınız - çoğunda CPU saat frekansında çalışacak şekilde ayarlanabilen bir zamanlayıcı / sayaç vardır. Kritik kodunuzun başında ve sonunda sayacın bir kopyasını yakalayın ve ne kadar sürdüğünü görebilirsiniz. Bunu yapamazsanız, başka bir alternatif kodunuzun başlangıcında bir çıkış pinini düşürmek ve sonunda yükseltmek ve yürütmeyi zamanlamak için bir osiloskopta bu çıkışa bakmaktır. Her bir yaklaşım için dengesizlikler vardır: dahili zamanlayıcı / sayaç daha esnektir (birkaç şeyi zamanlayabilirsiniz), ancak bilgiyi elde etmek daha zordur, oysa bir çıkış pimini ayarlamak / silmek bir kapsamda hemen görülebilir ve istatistikleri yakalayabilirsiniz, ancak birden fazla olayı ayırt etmek zor.
Son olarak, hem genel hem de özel işlemci / derleyici kombinasyonları ile deneyim ile gelen çok önemli bir beceri vardır: ne zaman ve ne zaman optimize edilmeyeceğini bilmek . Genel olarak cevap optimize etmektir. Donald Knuth alıntısı StackOverflow'da sıklıkla yayınlanır (genellikle sadece son kısım):
Zamanın yaklaşık% 97'sini küçük verimlilikleri unutmalıyız: erken optimizasyon tüm kötülüklerin köküdür
Ancak, bir çeşit optimizasyon yapmanız gerektiğini bildiğiniz bir durumdasınız, bu yüzden mermiyi ısırmanın ve optimize etmenin (veya daha hızlı bir işlemcinin veya her ikisinin birden) zamanı. Do DEĞİL montaj içinde tüm ISR yazın. Bu neredeyse garantili bir felaket - bunu yaparsanız, aylar veya haftalar içinde yaptığınız şeyin ve nedeninin parçalarını unutacaksınız ve kodun çok kırılgan ve değiştirilmesi zor olacak. Ancak, kodunuzun bölümlerini olması muhtemeldir vardır vardır montaj için iyi bir aday.
Kodunuzun bazı bölümlerinin montaj kodlaması için uygun olduğunu gösteren işaretler:
- iyi etkilenmeyen, iyi tanımlanmış küçük rutinleri içeren işlevler
- belirli montaj talimatlarını kullanabilen fonksiyonlar (min / maks / sağ kaydırma / vb.)
- defalarca çağrılan işlevler (sizi çarpanı alır: her çağrıda 0,5usec kaydederseniz ve 10 kez çağrılırsanız, bu da sizin durumunuzda önemli olan 5 usec tasarruf sağlar)
Derleyicinizin işlev çağırma kurallarını (örneğin, bağımsız değişkenleri kayıtlara koyduğu yeri ve hangi kayıtları kaydettiğini / geri yüklediğini) öğrenin, böylece C tarafından çağrılabilir montaj yordamları yazabilirsiniz.
Mevcut projemde, 10kHz'lik bir kesmede (100usec - ses tanıdık?) Çalıştırılması gereken kritik kodlu oldukça büyük bir kod tabanına sahibiz ve montajda yazılmış pek çok işlev yok. Bunlar, CRC hesaplaması, yazılım kuyrukları, ADC kazanç / ofset telafisi gibi şeylerdir.
İyi şanslar!