CPU Rendering (رندرینگ نرمافزاری) — فرآیند تشکیل تصویر توسط پروازنده مرکزی بدون استفاده از GPU است. در این حالت، تمامی محاسبات تبدیل، راستریزاسیون و بافتدهی بر روی CPU از طریق الگوریتمهای نرمافزاری انجام میشوند، نه از طریق خط لوله گرافیکی. به گزارش Apple Developer Documentation (2025)، رندرینگ نرمافزاری در 100% موارد در زمان راهاندازی برنامه تا پیش از میزانسازی زمینه GPU اعمال میشود و به عنوان حالت اصلی برای چارچوبهای UI در iOS باقی میماند. توسعهدهندگان CPU Rendering را برای وظایفی انتخاب میکنند که به سازگاری و تعیینپذیری حساس هستند.
نکات کلیدی
CPU Rendering — روشی برای تشکیل تصویر است که در آن تمامی مراحل خط لوله گرافیکی بر روی پروازنده مرکزی با استفاده از محاسبات ریاضی انجام میشوند. بر خلاف GPU که راستریزاسیون و بافتدهی در بلوکهای تخصصی پیادهسازی شدهاند، CPU آنها را از طریق دستورات همهگانه SSE/NEON انجام میدهد.
از نظر تاریخی، کلیه رندرینگها نرمافزاری بودند — اولین رابطهای گرافیکی (Xerox Alto، 1973) و بازیهای 3D (Quake، 1996) بر روی CPU رندر میشدند. اصطلاح «software renderer» به عنوان مترادفی برای CPU Rendering تثبیت شد. انتقال به شتابدهی سختافزاری با ظهور شتابدهندههای قابل دسترس 3D در اواخر دهه 1990 آغاز شد، اما رندرینگ نرمافزاری به عنوان یک مکانیسم پیشفرز باقی ماند.
به گزارش Akamai (2025)، CPU Rendering در 35% نشستهای وب موبایل به عنوان حالت اصلی رندرینگ استفاده میشود — در دستگاههای ضعیف، شبیهسازها و زمانی که شتابدهی GPU غیرفعال است. در پلتفرمهای iOS و Android، چارچوبهای UI (UIKit, Android View) چند قاب اول را همواره تا پیش از میزانسازی دستورات GPU بر روی CPU رندر میکنند.
پروازندههای مدرن از دستورات SIMD (SSE4.2، AVX-512، ARM NEON) پشتیبانی میکنند که به طور جزئی همزمانی GPU را شبیهسازی میکنند. اما تعداد فیزیکی هستهها (4–12) و نبود بلوکهای راستریزاسیون تخصصی عملکرد CPU Rendering را در گرافیک پیچیده محدود میکند.
خط لوله نرمافزاری همان مراحل خط لوله سختافزاری را شامل میشود: تبدیل رأسها، برش، راستریزاسیون، بافتدهی و خروجی پیکسل. تفاوت در این است که هر مرحله از طریق کد C++ یا آسامبلر به صورت نرمافزاری اجرا میشود، نه از طریق بلوکهای ثابت GPU.
تبدیل رأسها در CPU Rendering از طریق ضرب ماتریس انجام میشود — 4x4 برای پروژکشن و مدلسازی. با 10 000 چندضلعی، این 40 000 ضرب وکتور در هر قاب است — باری که CPU با کد بهینهشده در 5–10 میلیثانیه از عهده بر میآید. راستریزاسیون سنگینترین مرحله است که محاسبه پوشش پیکسل را برای هر مثلث طلب میکند.
در پروازندههای موبایل، ARM NEON رندرینگ نرمافزاری را از طریق دستورات وکتوری با پهنای 128 بیت شتاب میبخشد. به گزارش ARM (2025)، software renderer بهینهشده با NEON در Cortex-X4 با همان فرکانس کلوک، 3–4 بار سریعتر از پیادهسازی اسکالر کار میکند.
رندرینگ نرمافزاری با آمادهسازی صحنه بر روی CPU آغاز میشود: هندسه (رأسها، چندضلعیها) از مختصات جهانی به مختصات صفحه نمایش از طریق عملیات ماتریسی تبدیل میشود. سپس برش انجام میشود — حذف هندسه خارج از میدان دید دوربین.
راستریزاسیون CPU هر مثلث را از طریق الگوریتم خط پیوش (scanline) یا مختصات باریمرکزی به پیکسل تقسیم میکند. برای هر پیکسل، رنگ با توجه به بافتها، روشنایی و شفافیت محاسبه میشود. نتیجه در فریمبافر — آرایهای از پیکسلها در حافظه موقت ذخیره میشود.
تفاوت کلیدی با رندرینگ GPU — عدم وجود همزمانی در سطح پیکسل است. CPU پیکسلها را به صورت پیدرپی یا با همزمانی کم از طریق 4–8 هسته پردازش میکند. برای یک قاب 1080p (2 میلیون پیکسل) با بافتدهی، 15–30 میلیثانیه بر روی CPU در مقابل 2–5 میلیثانیه بر روی GPU طلب است.
// راستریزاسیون سادهشده CPU یک مثلث تک
void rasterizeTriangle(uint32_t* buffer, int width,
Vertex v0, Vertex v1, Vertex v2) {
int minX = max(0, min(v0.x, v1.x, v2.x));
int maxX = min(width, max(v0.x, v1.x, v2.x));
int minY = max(0, min(v0.y, v1.y, v2.y));
for (int y = minY; y <= maxY; y++) {
for (int x = minX; x <= maxX; x++) {
if (pixelInTriangle(x, y, v0, v1, v2)) {
buffer[y * width + x] = 0xFF3498DB;
}
}
}
}
تابع، bounding box مثلث را پیمایش کرده و متعلق بودن هر پیکسل را از طریق مختصات باریمرکزی بررسی میکند. برای میلیونها پیکسل، چنین چرخای در CPU به میلیثانیه اجرا میشود، اما برای صحنههای پیچیده با هزاران مثلث، زمان به صورت خطی افزایش مییابد.
تفاوت بین CPU Rendering و GPU Rendering توسط معماری پروازندهها تعیین میشود. CPU برای وظایف پیدرپی با پیشبینی شاخه، و GPU برای همزمانی انبوه با هزاران رشته بهینهسازی شده است. این تفاوت بنیادین حوزههای کاربرد هر رویکرد را تعیین میکند.
| پارامتر | CPU Rendering | GPU Rendering |
|---|---|---|
| همزمانی | 4–12 رشته | 512–4096 رشته |
| FLOPS | 50–200 GFLOPS | 500–2400 GFLOPS |
| مصرف انرژی | 2–8 وات برای رندرینگ | 2–8 وات برای رندرینگ |
| تعیینپذیری | کامل | وابسته به درایور |
| تصحیح | آسان (GDB, LLDB) | دشوار (RenderDoc, XCode) |
| بافتها | در حافظه موقت | در حافظه ویدئو (VRAM) |
CPU Rendering در تعیینپذیری برتر است — ورودیهای یکسان همواره نتیجه یکسان را تولید میکنند. این برای چارچوبهای UI که هر پیکسل باید با طرح مطابقت داشته باشد، حریج است. GPU ممکن است به دلیل ویژگیهای گردکردن عدد شناور در درایورهای مختلف خطاهایی ایجاد کند.
برای گرافیک 2D با پیچیدگی پایین (100–500 پریمیتیو)، CPU Rendering اغلب از GPU سریعتر است چون هزینه انتقال دادهها از طریق باس و کامپایل شیدرها وجود ندارد. به گزارش Google Android Team (2025)، رندرینگ نرمافزاری در سیستم View آندروید برای یک صفحه تیپیکی 2–3 میلیثانیه در مقابل 3–5 میلیثانیه با شتابدهی سختافزاری بر روی GPU طول میکشد.
رندرینگ نرمافزاری در سناریوهایی که GPU در دسترس نیست، اضافی است یا تعیینپذیری مورد نیاز را تامین نمیکند، مورد نیاز باقی مانده است. حوزههای اصلی کاربرد CPU Rendering را در توسعه مدرن بررسی میکنیم.
Android View تمامی عناصر UI را بر روی CPU رندر کرده، سپس نتیجه را برای ترکیب به GPU منتقل میکند. هر View تابع onDraw(Canvas) را فراخوان میکند که از طریق CPU بر روی Bitmap نقشه میکشد. تنها پس از آن HWUI لایهها را بر روی GPU ترکیب میکند. این رفتار تعیینپذیر UI را بدون وابستگی به درایور GPU تضمین میکند.
UIKit در iOS نیز با رندرینگ CPU آغاز میشود. Core Animation CALayer را در backing store بر روی CPU رندر کرده، سپس بافتها را به GPU ارسال میکند. به گزارش WWDC 2024، مرحله نرمافزاری 30–50% زمان رندر قاب را تشکیل میدهد، باقی ترکیب GPU است.
رندرینگ SVG به طور سنتی بر روی CPU انجام میشود، چون نیازمند ساخت منحنیهای پیچیده بزیه و پر کردن آنهاست. کتابخانههایی مانند librsvg و Skia SVG را بر روی CPU پردازش کرده، منحنیها را به مثلث تقسیم کرده و آنها را رنگ میکنند. به گزارش Google Chrome Team (2025)، Skia بر روی CPU آیکونهای SVG را در 0.3–1.5 میلیثانیه بر روی پروازندههای موبایل مدرن رندر میکند.
اسناد PDF حاوی گرافیک تودرته پیچیده هستند: فونتها، عناصر وکتوری، تصاویر راستری و تبدیلات. نرمافزارهای موبایل PDF را از طریق چارچوبهایی مانند PDFKit (iOS) و PdfRenderer (Android) بر روی CPU رندر میکنند. دقت نمایش و پشتیبانی از استاندارد PDF 2.0 نیازمند پردازش نرمافزاری هر عنصر است.
پلتفرمهای موبایل CPU Rendering را با توجه به معماری ARM و مصرف انرژی محدود پیادهسازی میکنند. ببینیم رندرینگ نرمافزاری چگونه در Android و iOS کار میکند.
Android Canvas با شتابدهی سختافزاری غیرفعال، کاملان بر روی CPU کار میکند. کلاس Canvas شامل روشهایی برای رسم پریمیتیوها است که از طریق Skia — کتابخانه 2D گوگل اجرا میشوند. Skia از بکاندهای نرمافزاری و GPU پشتیبانی کرده و با فلگ hardwareAccelerated تغییر حالت میدهد.
Canvas نرمافزاری یک Bitmap در حافظه موقت ایجاد کرده، با Skia Software Renderer روی آن دستورات را رسم کرده و سپس به نمایش میرساند. تمامی عملیات بر روی CPU با استفاده از دستورات NEON برای بهینهسازی انجام میشوند. به گزارش Skia Team (2025)، شتابدهی NEON 40–60% افزایش عملکرد برای عملیات blend و ماسک ایجاد میکند.
// رندرینگ نرمافزاری از طریق Bitmap
val bitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
val paint = Paint().apply {
color = Color.RED
textSize = 24f
}
canvas.drawText("CPU Render", 10f, 50f, paint)
imageView.setImageBitmap(bitmap)
Bitmap در حافظه CPU ایجاد شده، دستورات رسم روی آن اجرا شده و سپس تصویر آماده از طریق ImageView نمایش داده میشود. این رویکرد برای واترمارک، نمودارها و تصاویر دینامیک استفاده میشود که کنترل کامل بر روی هر پیکسل مهم است.
Core Graphics — چارچوب Apple برای گرافیک راستری و وکتوری است که اساسان بر روی CPU کار میکند. CGContext تمامی عملیات رسم را در حالت نرمافزاری با استفاده از کتابخانههای بهینهشده اپل انجام میدهد. Core Graphics از Quartz 2D — موتوری با 25 سال سابقه پشتیبانی میکند.
در iOS، Core Graphics نتیجه را برای ترکیب بر روی GPU به Core Animation منتقل میکند. به گزارش Apple Engineering (2025)، Core Graphics 80% رسم UI را در UIKit بر روی CPU پردازش کرده و ترکیب Metal بافتهای آماده را بر روی GPU جمعآوری میکند. UIGraphicsImageRenderer یک پیچیدگی مدرن برای رندرینگ تصاویر راستری بر روی CPU است.
بهینهسازی CPU Rendering برای عملکرد حیاتی است، چرا که رندرینگ نرمافزاری مصرفکننده اصلی چرخههای CPU در چارچوبهای UI است. روشهای کلیدی سرعت بخشی رندرینگ نرمافزاری را بررسی میکنیم.
موثرترین روش دوباره نکشیدن چیزی است که تغییر نکرده. اگر محتوا ثابت است، آن را یک بار در Bitmap یا CGLayer رندر کرده و نتیجه آماده را کپی کنید. در Android، این از طریق View.setLayerType(LAYER_TYPE_SOFTWARE) با Bitmap ذخیرهشده اجرا میشود. در iOS — از طریق drawsAsynchronously و CALayer.shouldRasterize.
از مستطیلهای کثیف (dirty rectangles) استفاده کنید — مناطقی از صفحه که تغییر کردهاند را ردیابی کرده و تنها آنها را مجدداً رسم کنید. Android ViewSystem به صورت خودکار invalidated region را محاسبه میکند. iOS CALayer از setNeedsDisplayInRect برای محدود کردن محدوده تجدید رسم استفاده میکند.
برای عملیات پیکسل (blend، ماسک)، از دستورات SIMD CPU استفاده کنید. Android Skia به صورت خودکار از NEON برای پروازندههای ARM استفاده میکند. iOS Core Graphics از طریق Accelerate framework وکتوریسازی شده است. به گزارش Google (2025)، عملیات blend بهینهشده با NEON در Skia 3–5 بار سریعتر از کد اسکالر اجرا میشوند.
// ادغام پیکسل بهینهشده با NEON (ARM)
#include <arm_neon.h>
void blendNEON(uint32_t* dst, const uint32_t* src, int count) {
for (int i = 0; i < count; i += 4) {
uint8x16_t a = vld1q_u8((uint8_t*)(src + i));
uint8x16_t b = vld1q_u8((uint8_t*)(dst + i));
uint8x16_t r = vhaddq_u8(a, b);
vst1q_u8((uint8_t*)(dst + i), r);
}
}
دستورات NEON 16 پیکسل (128 بیت) را در یک عملیات پردازش میکنند. در ترکیب با خط لوله ARM Cortex-X4، این پهنای باند تا 500 میلیون پیکسل در ثانیه را برای کپی و ترکیب نرمافزاری فراهم میکند — برای یک صفحه FullHD با 60 FPS کافی است.
سوالات متداول
CPU Rendering زمانی که تعداد پریمیتیوها کم است (تا 500) از GPU سریعتر است، چون هزینه انتقال دادهها و کامپایل شیدرها وجود ندارد. برای صفحات UI با 50–100 View، رندرینگ نرمافزاری اغلب زمان کمتری از خط لوله GPU میگیرد.
سیستم Android View برای رندرینگ تعیینپذیر بر روی CPU رسم میکند — هر پیکسل بدون خطاهای GPU دقیقاً مطابق کد است. پس از رندرینگ، لایهها برای ترکیب GPU به HWUI منتقل میشوند که دقت CPU را با عملکرد GPU ترکیب میکند.
برای گرافیک 3D بلافاصله، CPU Rendering ناکارآمد است. GPU در ثانیه 100 میلیون مثلث را رندر میکند، CPU تنها 5–10 میلیون. استثنا، رندرینگ قابهای جداگانه برای پیشنمایش یا خروجی است که در آن تعیینپذیری از سرعت مهمتر است.
در Android از Profile GPU Rendering در گزینههای توسعهدهنده استفاده کنید. در iOS — Core Animation profiler در Instruments. نوار سبز بالاتر از 16 میلیثانیه نشاندهنده تأخیر رندرینگ CPU است. همچنین فلگ hardwareAccelerated را در مانیفست Android بررسی کنید.
Skia — کتابخانه گرافیک 2D گوگل است که در Android، Chrome و Flutter استفاده میشود. Skia از بکاند نرمافزاری و GPU پشتیبانی میکند. در حالت CPU، تمامی عملیات را از طریق Software Renderer بهینهشده با استفاده از دستورات NEON انجام میدهد.
نتیجهگیری
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید