Apakah mungkin untuk memantau blok kode dan menentukan jumlah siklus jam prosesor yang diambil oleh prosesor Arduino dan / atau prosesor atm AVR? atau, haruskah saya lebih suka memonitor mikrodetik yang dilewati sebelum dan sesudah kode dijalankan? Catatan: Saya tidak peduli dengan waktu nyata (seperti pada, berapa detik nyata berlalu) sebanyak saya di "berapa banyak siklus jam yang dibutuhkan kode ini dari CPU"
Solusi saat ini yang dapat saya buat adalah dari time.c:
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
wiring.c menambahkan:
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
Dengan akun ini saya bisa menghitung clock cyles yang dilewati dengan memonitor microsecond yang berlalu dan kemudian meneruskannya ke microsecondsToClockCycles (). Pertanyaan saya adalah, adakah cara yang lebih baik?
sidenote: apakah ada sumber daya yang baik untuk memantau kinerja AVR. lmgtfy.com dan berbagai pencarian forum tidak memberikan hasil yang jelas, selain eksplorasi timer
Terima kasih
Apa yang Anda maksud dengan "monitor"?
Seharusnya tidak sulit untuk menghitung siklus clock untuk AVR untuk potongan kecil kode perakitan.
Anda juga dapat mengatur porta sebelum kode dieksekusi dan meresetnya sesudahnya, dan memonitornya dengan penganalisis logika atau oszilloscope untuk mendapatkan waktunya.
Dan Anda juga bisa membaca waktu dari timer yang berjalan cepat, seperti yang Anda katakan.
sumber
Ini adalah contoh untuk Arduino menggunakan fungsi clockCyclesPerMicrosecond () untuk menghitung jam yang telah berlalu. Kode ini akan menunggu 4 detik, lalu mencetak waktu berlalu sejak awal program. Nilai 3 kiri adalah total waktu (mikrodetik, milidetik, siklus total jam) dan sebagian besar 3 adalah waktu yang telah berlalu:
Keluaran:
Saya yakin ada penjelasan yang masuk akal mengapa loop pertama juga memiliki siklus jam berlalu lebih pendek daripada kebanyakan dan mengapa semua loop lain beralih antara dua siklus clock panjang.
Kode:
Sidenote: jika Anda menghapus penundaan 4 detik Anda akan mulai melihat efek dari Serial.print () jauh lebih jelas. Catatan, di sini 2 run dibandingkan. Saya hanya memasukkan 4 sampel dekat satu sama lain dari log masing-masing.
Jalankan 1:
Jalankan 2:
Waktu yang berlalu meningkat dari total waktu berjalan. Setelah sedetik berlalu, jam meningkat rata-rata dari 40k menjadi 44k. Ini terjadi secara konsisten beberapa milidetik setelah 1 detik dan jam yang berlalu tetap sekitar 44r untuk setidaknya 10 detik berikutnya (saya belum mengujinya lebih lanjut). Inilah mengapa pemantauan bermanfaat atau dibutuhkan. Mungkin penurunan efisiensi berkaitan dengan konfigurasi atau bug dalam serial? Atau mungkin kodenya tidak menggunakan memori dengan benar dan memiliki kebocoran yang memengaruhi kinerja, dll.
sumber
Karena setiap baris kode yang ditambahkan ke sumber Anda akan berdampak pada kinerja dan dapat mengubah optimasi yang diterapkan. Perubahan harus menjadi minimum yang diperlukan untuk melakukan tugas.
Saya baru saja menemukan plugin Atmel Studio yang disebut "Debugger File Anotasi Majelis". http://www.atmel.com/webdoc/aafdebugger/pr01.html Sepertinya melangkah melalui bahasa assembly yang dihasilkan sementara mungkin membosankan akan menunjukkan kepada Anda apa yang terjadi. Anda mungkin masih harus men-decode berapa banyak siklus yang diperlukan untuk setiap instruksi tetapi itu akan jauh lebih dekat daripada beberapa opsi lain yang diposting.
Bagi mereka yang tidak tahu di folder Output proyek Anda adalah file dengan ekstensi LSS. File ini berisi semua kode sumber asli Anda sebagai komentar dan di bawah setiap baris adalah bahasa rakitan yang dihasilkan berdasarkan baris kode tersebut. Membuat file LSS dapat dimatikan, jadi periksa pengaturan berikut.
Properti Proyek | Toolchain | AVR / GNU Common | OutputFiles
Kotak centang ".lss (Hasilkan file lss)
sumber
Anda dapat menggunakan salah satu timer bawaan. Dapatkan semuanya diatur untuk prescaller = 1 dan TCNT = 0 sebelum blok. Kemudian aktifkan timer di telepon sebelum blok dan nonaktifkan di telepon setelah blok. TCNT sekarang akan menahan jumlah siklus yang diambil blok, dikurangi siklus tetap untuk kode aktifkan dan nonaktifkan.
Perhatikan bahwa TNCT akan meluap setelah 65535 clock cycle pada timer 16 bit. Anda dapat menggunakan flag overflow untuk menggandakan waktu lari. Jika Anda masih membutuhkan lebih lama, Anda dapat menggunakan prescaler, tetapi akan mendapatkan resolusi lebih sedikit.
sumber