කේතයක් වැඩිදියුණු කිරීමෙන් පසු හදිසි බග් එකක් පෙනෙන්නට හැකියි. වැඩි කාර්ය සාධනයක් කියලා හිතපු දත්ත ව්යුහයක් හුදෙක් පරිසරය තුළ CPU භාවිතය ගිණුම් ගණනකට ගෙන එයි. මේ ලිපියෙදී එවැනි සිදුවීමක් Raspberry Pi‑ක audio player එකකදී කොහොමත් සිදු වුණා කියලා බලමු.
Kalinka Player කියන සංගීත ධාවකයක් Raspberry Pi‑වල ධාවනය වෙයි. එහි මූලික කොටසක් bounded producer/consumer buffer එකක්, ජාල/decoder thread එකෙන් audio bytes පසුපසට ලියලා, audio output thread එකෙන් ඉදිරියට කියවලා ඉවත් කරනවා. දත්ත වර්ගය uint8_t සහ buffer අඩංගු ප්රමාණය 768KB‑දක්වා (HTTP) හෝ 1.5 MB (FLAC) පමණයි.
මුලින්ම buffer එක std::deque<T> මගින් සකස් කර තිබුණා. ලිවීමේ (write) සහ කියවීමේ (read) දෙකම mutex එකක් ගෙන lock කරලා, insert සහ erase භාවිතා කරා. මෙන්න ඒ කොඩ් එකේ සාරාංශය:
- write: data.insert(data.end(), source, source + n);
- read: std::copy_n(data.begin(), n, dest); data.erase(data.begin(), data.begin() + n);
FIFO පටිපාටියට රින්ග් බෆරයක් (circular buffer) පරිපූර්ණයි කියලා හිතලා, boost::circular_buffer එකට මාරු කළා. එය එකම memory allocation එකක්, දෙකේ index දෙකක් පමණක් භාවිතා කරන නිසා allocation churn එකක් නැති බවට විශ්වාසයක් තිබුණා.
මයික්රොබෙන්ච්මාර්ක් එකක් රචනා කරලා, 32‑byte records 20 M operations ක් පරීක්ෂා කළා. එතැන circular buffer එක 2‑3× වේගවත් බව පෙන්වා දුන්නා:
- 64 capacity: 845 Mops/s vs 304 Mops/s
- 1024 capacity: 813 Mops/s vs 295 Mops/s
- 65536 capacity: 614 Mops/s vs 280 Mops/s
ඒ අනුව, 2024‑09‑11 දින commit කරලා deque‑වෙතින් circular buffer එකට මාරු කළා. ඒත් වැඩේ සම්පූර්ණයෙන්ම වෙනස් වුණා: CPU භාවිතය 1‑3% සිට 20‑30% දක්වා ගොඩක් වැඩිය. Raspberry Pi එකේ තාපය, බැටරි ආයුෂය වගේ ප්රභේද වලට මේක බරක් වුණා.
කාරණය පැහැදිලි වුණා: read() ක්රමය තුළ erase භාවිතා කිරීමයි. circular buffer එකට erase_begin(n) නම් විශේෂ method එකක් තියෙනවා, එය internal start index එකක් ඉදිරියට ගෙන යනවා, ඒත් සාමාන්ය erase භාවිතා කළාම එය සාමාන්ය erase machinery එකක් හරහා ගිය නිසා CPU වැඩිය.
2024‑09‑18 දින ඒක erase_begin(sizeToCopy) වලට වෙනස් කළා. ඒකෙන් එකක් පමණක් 2 ms සිට 0.02 ms දක්වා 100× වේගය වැඩි වුණා. නමුත් එය CPU භාවිතය පැරණි deque මට්ටමට පත් නොකරලා. std::deque තවමත් byte‑stream FIFO සඳහා 2× වඩා හොඳයි.
ශ්රී ලංකාවට ඇති වැදගත්කම
මෙම සිදුවීම ලංකාවේ තරුණ developers, විද්යා ශිෂ්යයන් සහ තාක්ෂණික ව්යාපාර සඳහා වැදගත් පණිවුඩයක් ලබා දෙයි:
- දත්ත ව්යුහ තේරීමේ වැදගත්කම: කේතයක් “වැඩි හොඳ” කියලා හිතලාම එය අත්හදා බැලීම අත්යවශ්ය. මයික්රොබෙන්ච්මාර්ක් එකක් පමණක් නොව, real‑world workload එකත් සමඟ පරීක්ෂා කිරීම අත්යවශ්ය.
- Raspberry Pi වැනි embedded platform වල සම්පත් සීමා: CPU, තාපය, බැටරි ආයුෂය යන සීමා ඇති පද්ධති වල performance regression එකක් වහාම හඳුනාගැනීම වැදගත්.
- Boost library භාවිතයේ අවධානම: Boost ලාභදායී නමුත්, library‑specific API (erase_begin) ගැන අවධානයෙන් ඉගෙන ගත යුතුයි.
- ඉගෙනුම් අවස්ථාව: ශ්රී ලංකාවේ C++ පාඨමාලා, university projects, සහ startup prototypes වල මෙවැනි උදාහරණය භාවිතා කරලා real‑world performance optimisation කුසලතා වර්ධනය කළ හැක.
අවසන් වශයෙන්, “ඉක්මන්” දත්ත ව්යුහයක් තේරීමේදී එය ඇත්තටම වැඩිදියුණු කරන්නේ කුමක්දැයි සැලකිල්ලෙන් පරීක්ෂා කිරීම අත්යවශ්ය. වැඩි CPU භාවිතය ඔබේ පද්ධතියේ වියදම, පරිසරය, සහ පරිශීලක අත්දැකීමට බලපායි.