من الخوارزمية إلى الدوائر الإلكترونية
كل ما تناولناه في هذه الدورة — المرشحات والتحويلات والارتباط ومعالجة الإشارات متعددة المعدلات — يُنفَّذ في نهاية المطاف على أجهزة حقيقية. في المنتجات الفعلية، يكون هذا الجهاز عادةً معالجاً مضمَّناً صغيراً محدود الطاقة، وليس محطة عمل مكتبية. إن فهم كيفية تعيين خوارزميات معالجة الإشارات الرقمية على الأجهزة المضمَّنة هو الجسر بين النظرية والملايين من الأجهزة التي تعالج الإشارات حولنا كل يوم: سماعات الرأس والهواتف الذكية وأجهزة المراقبة الطبية ومتحكمات المحركات وأجهزة استقبال الأقمار الاصطناعية.
تأتي معالجة الإشارات الرقمية المضمَّنة مع قيود صارمة نادراً ما يواجهها مهندسو البرمجيات على أجهزة الكمبيوتر العامة: ذاكرة محدودة (غالباً كيلوبايتات لا غيغابايتات)، وميزانيات طاقة صارمة، ومواعيد نهائية لا تقبل المساومة في الوقت الفعلي. إن فاتَك إطار عينة واحدة، ينتج عن ذلك صوت تالف أو حزمة اتصالات مفقودة أو خطأ في التحكم بالمحرك. يستلزم التعامل مع هذه القيود فهمَ تنسيقات الحساب ومعماريات المعالج وتقنيات تحسين الكود.
معالجة الإشارات الرقمية المضمَّنة هي موازنة ثلاثية الاتجاهات بين سرعة الحساب واستهلاك الطاقة والدقة العددية. كل قرار تصميمي يُغيّر هذه الموازنة. اختيار الفاصلة الثابتة بدلاً من الفاصلة العائمة، على سبيل المثال، يُخفض الطاقة بمقدار 10 أضعاف لكنه يتطلب ضبطاً دقيقاً لتجنب الفيض وضوضاء التكميم.
الحساب بالفاصلة الثابتة مقابل الفاصلة العائمة
الاختيار الأساسي في معالجة الإشارات الرقمية المضمَّنة هو كيفية تمثيل الأرقام. تُشفِّر أرقام الفاصلة العائمة (IEEE 754، دقة مفردة 32 بت) نطاقاً ديناميكياً واسعاً تلقائياً — تتحرك الفاصلة العشرية إلى حيث تحتاج. هذا يجعل تطوير الخوارزميات مباشراً: نادراً ما تقلق بشأن الفيض أو التحجيم. والعقوبة هي التكلفة على مستوى الأجهزة: تستهلك وحدة الفاصلة العائمة (FPU) مساحة كبيرة على الشريحة وطاقة كبيرة.
تُمثِّل أرقام الفاصلة الثابتة القيمَ بوصفها أعداداً صحيحة مُعامَلة. تنسيق Q15، على سبيل المثال، يخزّن عدداً صحيحاً من 16 بتاً تقع فيه الفاصلة الثنائية الضمنية بعد بت الإشارة وقبل 15 بتاً كسرية، مما يعطي نطاقاً من −1 إلى أقل بقليل من +1 بدقة 2−15 ≈ 30.5 µV إذا كان الحد الأقصى للحجم الكامل 1 فولت. لا يتطلب حساب الفاصلة الثابتة وحدة FPU ويعمل على أجهزة الأعداد الصحيحة البسيطة، مما يستهلك طاقة وموارد رقاقة أقل بكثير.
الخطر الرئيسي في حساب الفاصلة الثابتة هو الفيض: إذا أنتجت عملية ضرب أو تجميع نتيجةً خارج النطاق القابل للتمثيل، تلتف القيمة بشكل كارثي. التحجيم الدقيق — اختيار موضع الفاصلة الثنائية وكمية هامش الأمان المتروك — هو المهارة الجوهرية في برمجة DSP بالفاصلة الثابتة. الحساب بالتشبّع (التثبيت عند القيمة القصوى القابلة للتمثيل بدلاً من الالتواء) ميزةٌ أجهزية في معظم أنوية DSP تُخفّف الفيض بأناقة.
معماريات معالجات DSP
المعالجات العامة (ARM Cortex-A، x86) محسَّنة لأنماط التشعّب والوصول إلى الذاكرة النموذجية في أنظمة التشغيل والتطبيقات. أما معالجات DSP فهي محسَّنة للحلقات المتكررة كثيفة البيانات في صميم معالجة الإشارات: عمليات الضرب والتجميع، والتخزين الدائري، والعنونة المعكوسة للبتات في تحويل فورييه السريع.
تعدّ عائلة TI C6000 (مثل C6748 وC66x) معالجات DSP عالية الأداء ذات كلمة تعليمات طويلة جداً (VLIW) تتضمن وحدات تنفيذ متعددة تعمل بالتوازي. يمكن لنواة C6748 واحدة أن تُنجز 3000 مليون عملية ضرب وتجميع في الثانية (3000 MMACS) مع استهلاك أقل من 1 واط. وهي متواجدة في كل مكان في معالجة الصوت والتصوير الطبي والمودمات.
تجلب وحدات ARM Cortex-M الدقيقة (M4 وM7 وM33 وM55) قدرة DSP إلى المتحكمات الدقيقة فائقة توفير الطاقة. أضاف Cortex-M4 وحدة FPU بدقة مفردة وتعليمات SIMD — تنفيذ عمليتَي ضرب بـ16 بتاً بتعليمة واحدة. ويضيف Cortex-M55 امتداد Helium المتجه، مما يُتيح ثماني عمليات MAC بـ16 بتاً في آنٍ واحد. تعمل هذه الأجهزة بمليأمبيرات من التيار، مما يجعلها مثالية لأجهزة الاستشعار القابلة للارتداء والإنترنت الأشياء.
تتضمن كل معالجات DSP وحدة الضرب والتجميع (MAC) المخصصة التي تحسب y += a × b في دورة ساعة واحدة. تُختزل الالتوائية والترشيح والارتباط جميعها في عمليات MAC متكررة. وحدة MAC بـ32 بتاً مع مجمِّع بـ64 بتاً (شائع في DSPs ذات 16 بتاً بالفاصلة الثابتة) تمنع الفيض أثناء تجميع مئات الضربات قبل تحجيم النتيجة النهائية وتخزينها.
قيود الذاكرة والحساب
الذاكرة في DSP المضمَّن شحيحة ومكلفة (من حيث الطاقة ومساحة الشريحة) ومهمة معمارياً. تُوفِّر معالجات DSP عادةً ذواكر منفصلة للتعليمات والبيانات (معمارية هارفارد) بحيث يمكن للمعالج جلب التعليمة التالية وتحميل قيمة بيانات في آنٍ واحد، متجنباً عنق زجاجة فون نيومان.
يجب أن تتسع جداول معاملات المرشحات وذاكرات العينات الدائرية في ذاكرة SRAM على الشريحة أو الذاكرة المقترنة بإحكام (TCM) لتجنب عقوبة الكمون التي تبلغ 10 إلى 100 ضعف عند الوصول إلى ذاكرة DRAM الخارجية. لمرشح FIR ذي 256 نقرة بتنسيق Q15، تستهلك جدول المعاملات 512 بايت — تسعها الشريحة بسهولة. أما ذاكرة العمل لتحويل FFT بـ1024 نقطة بتنسيق مركب 32 بت فتتطلب 8 كيلوبايت — لا تزال على الشريحة لمعظم أجزاء Cortex-M7 لكنها تستحق الانتباه في الميزانية.
المخازن الدائرية (الحلقية) هي بنية البيانات القياسية لتطبيق خطوط التأخير في المرشحات وملغيات الصدى. يلتف المؤشر بالنسبة المئوية لطول المخزن، متجنباً تكلفة إزاحة المصفوفة بأكملها مع كل عينة جديدة. تدعم معظم معماريات معالجات DSP العنونة الحلقية البرمجية التي تُنفِّذ التخزين الدائري بلا أي حمل إضافي.
متطلبات المعالجة في الوقت الفعلي
يجب على نظام DSP في الوقت الفعلي معالجة كل عينة إدخال (أو كتلة من العينات) ضمن موعد نهائي صارم. بالنسبة للصوت بـ48 كيلوهرتز، يملك المعالج 20.83 ميكروثانية بالضبط لكل عينة. في معالج نطاق أساسي بسرعة رمز 100 ميغاهرتز لشبكة 5G، الموعد النهائي هو 10 نانوثانية. يُفضي فوات الموعد إلى تجاوز المخزن: تستبدل العينة الجديدة عينةً لم تُعالَج بعد، مما ينتج عنه نقرة مسموعة أو رمز مفقود أو خطأ في التحكم.
تُطفئ معالجة الكتل الحمل الزائد للمقاطعات بجمع العينات في إطارات (مثلاً 64 أو 256 عينة) ومعالجة الإطار بأكمله دفعةً واحدة. يزداد زمن الاستجابة (التأخير من الإدخال إلى الإخراج) إلى مدة إطار واحد — وهو مقبول لمعظم تطبيقات الصوت والاتصالات — لكن كفاءة الإنتاجية تتحسن بشكل ملحوظ. تحويل FFT هو خوارزمية كتل بطبيعته ويندمج بشكل طبيعي في هذا النموذج.
الوقت الفعلي لا يعني أن تكون سريعاً — بل أن تكون سريعاً بشكل متوقع. نظام يعالج معظم الإطارات في 5 ميكروثانية لكنه يأخذ 25 ميكروثانية أحياناً سيتجاوز الموعد النهائي. تُسهم كمونات المقاطعة وعدم إصابة ذاكرة التخزين المؤقت وعمليات نقل DMA وسوء توقع التفريع في أسوأ وقت تنفيذ (WCET). كود DSP المضمَّن يُكتب لـتقليل هذه التباينات وتحديدها بحد أقصى، لا مجرد تحسين المتوسط.
تحسين الكود لـDSP
كتابة كود DSP يستوفي مواعيد الوقت الفعلي على أجهزة محدودة الطاقة تتطلب عملية تحسين منضبطة. أكثر التقنيات تأثيراً، بترتيب الأهمية تقريباً:
استخدام مكتبات المزوّد المحسَّنة. تُوفِّر ARM CMSIS-DSP وTI DSPLIB تطبيقات لغة التجميع المضبوطة يدوياً لمرشحات FIR وتحويلات FFT وعمليات المصفوفات وغيرها. مكتبة FFT أسرع عادةً بـ5 إلى 10 أضعاف من تطبيق C المباشر لأنها تستغل SIMD والفك اليدوي للحلقات وأنماط الوصول إلى الذاكرة الملائمة للتخزين المؤقت. لا تُعد ما فعلته المكتبة بشكل أفضل.
استغلال SIMD والمتطوعات. يمكن لأنوية DSP الحديثة معالجة مسارات بيانات متعددة بالتوازي. يعالج ARM Cortex-M4 SIMD عمليتَي MAC بـQ15 لكل دورة باستخدام تعليمة SMLAD. كتابة ذلك في C عبر المتطوعات (مثل __SMLAD()) يتجنب لغة التجميع مع توليد كود مثالي. الحلقة الداخلية المكتوبة يدوياً باستخدام SIMD يمكنها مضاعفة الإنتاجية مرتين إلى أربع مرات مقارنةً بالكود القياسي.
تجنب التفريع المعتمد على البيانات في الحلقات الحرجة. الانتقالات الشرطية في الحلقات الداخلية تتسبب في توقف خط الأنابيب. الحساب بالتشبّع والتعليمات المشروطة وفك لفّ الحلقات تُزيل التفريع من المسار الحرج. خيار المترجم -funroll-loops يُساعد، لكن فك الحلقات يدوياً لحلقات التكرار الثابت (مثل مرشح FIR بـ32 نقرة) غالباً أفعل.
الإدارة العدوانية لتسلسل هرمية الذاكرة. يجب أن تعيش معاملات المرشح وذاكرات العينات في أسرع ذاكرة متاحة (L1 SRAM أو TCM). عمليات نقل DMA من ذاكرة Flash الخارجية الأبطأ أو SDRAM يجب أن تعمل في الخلفية، تنقل بين مخزنَين بديلَين حتى يحسب المعالج دائماً على مخزن ممتلئ بينما يملأ DMA المخزن التالي.
- يُقايض حساب الفاصلة الثابتة (Q15 وQ31) مرونة النطاق الديناميكي بتكلفة طاقة وأجهزة أقل بكثير؛ والتحجيم الدقيق والحساب بالتشبّع يمنعان الفيض.
- تُوفِّر معالجات DSP المخصصة (TI C6000) والمتحكمات الدقيقة المعززة بـDSP (ARM Cortex-M4/M7/M55) وحدات MAC بدورة واحدة وتعليمات SIMD وعنونة مخزن دائري ضرورية للأداء في الوقت الفعلي.
- تُزيل معمارية هارفارد الذاكرية وذاكرة SRAM/TCM على الشريحة عنق زجاجة الذاكرة؛ ويجب وضع المعاملات والمخازن العاملة في أسرع طبقة ذاكرة متاحة.
- تتطلب المعالجة في الوقت الفعلي أسوأ وقت تنفيذ متوقعاً، لا مجرد أداء متوسط سريع؛ ومعالجة الكتل والتخزين المزدوج بـDMA وإزالة التفريع هي التقنيات الرئيسية.
- توفر مكتبات DSP المُحسَّنة من المزوّدين (CMSIS-DSP وDSPLIB) أداء SIMD المضبوط يدوياً؛ استخدامها نقطة انطلاق قبل كتابة كود تجميع مخصص.
- يجب إبقاء حمل وحدة المعالجة أقل بكثير من 100% لترك هامش للمقاطعات وحمل نظام التشغيل والميزات المستقبلية دون إثارة تجاوزات في المخازن.