المدونة

الإنتاجية لكل دورة معالج: الرقم الذي ينجو من ملامسة موجّه حقيقي

رقم المختبر ورقم العتاد الحقيقي لا يتفقان تقريبًا أبدًا. قِسنا كليهما، واحتفظنا بهوامش الثقة، وكشفنا عن الفخ الذي أنتج مرة نتيجة خاطئة، وقلنا بوضوح أين خسرنا.

نُشر في 6 سبتمبر 2026

على موجّهين ماديين، ينقلان حركة مرور حقيقية عبر شبكة محلية حقيقية بسرعة غيغابت، دفع نواة النفق لدينا 122 ميغابت/ثانية بينما دفعت تطبيق النفق الخاص بنواة الموجّه نفسه (kernel tunnel) 66.8 ميغابت/ثانية — على المُرسل نفسه، وبمعالجة أقل لكل ميغابت. لا يروي أي من الرقمين القصة كاملة بمفرده: احتاج الجانبان إلى استخدام مولّدَي حركة مرور مختلفين، لأنه لا يوجد مولّد واحد يعمل على جانبي تلك المقارنة. لذا فإن النسبة التي تستحق النقاش هي كل جانب مقابل سقفه الخاص بلا نفق، وهو ما يظهر في الجدول أدناه ويفضّلنا بفارق أكبر، لا أقل. تجربة مختبرية بأربعة أجهزة افتراضية على حاسوب محمول تقول شيئًا أسرع بالقيم المطلقة، وعلى محور واحد، شيئًا أقل مجاملة. نحن نثق برقم الموجّه أكثر، لأن الموجّه هو الوحيد من الاثنين الذي تعبره حركة مرور عميل فعليًا.

تلك هي النتيجة التي تستحق أن تُفتتح بها، وهي أيضًا سبب احتواء هذا المقال على قسمي نتائج بدلًا من قسم واحد: يختلف المختبر والعتاد الحقيقي حول أي محور هو المهم، والتستّر على ذلك الخلاف كان سيكلّف مصداقية أكبر مما يكسبه أي من الرقمين.

اقرأ هذا قبل الأرقام. تُنفَّذ طبقة بياناتنا افتراضيًا على خيط معالجة واحد (thread). أما المقارَن الذي شغّلناه إلى جانبها في المختبر فيُنفَّذ افتراضيًا على أربعة. من دون معادلة، تُحرّك هذه العلامة وحدها إنتاجيته من نحو 789 إلى 1427 ميغابت/ثانية — فجوة في الإعدادات الافتراضية، لا في مسارات البيانات — وقد أنتجت بالفعل رقمًا خاطئًا منشورًا هنا من قبل. كل رقم مختبري أدناه يُثبّت كلا نواتَي Rust على خيط واحد. أما تطبيقا Go والنواة (kernel) في ذلك الجدول فقد عملا بإعداداتهما الافتراضية، التي تستخدم أكثر من خيط واحد — وهو ما يميل لصالحهما مقابل خيطنا الواحد إن كان له أثر أصلًا. تُعرض فجوة الإعداد الافتراضي كما شُحنت بشكل منفصل، مرة واحدة، حتى لا تختفي بالإغفال أيضًا.

ما الذي قِيس، وعلى ماذا

بيئتان مستقلتان، لأن أي اختبار أداء (benchmark) لا يكون صادقًا إلا ضمن البيئة التي أُجري فيها — رقم iperf3 ورقم bandwidth-test ليسا رقمًا واحدًا بحلّتين، وجهاز افتراضي يتشارك أنوية حاسوب محمول ليس موجّهًا.

العتاد — موجّها MikroTik، شبكة محلية واحدة بسرعة غيغابت، بتاريخ 2026-09-01. RB3011UiAS (بمعمارية ARMv7، معالج ثنائي النواة 1400 ميغاهرتز) كمُرسل، وcAP ax (بمعمارية ARM64، رباعي النواة 864 ميغاهرتز) كمُستقبل، وRouterOS 7.24.1 على كليهما. عملت نواتنا كـfv، داخل حاوية RouterOS، في مساحة المستخدم (userspace)، مقابل تطبيق WireGuard-protocol المدمج في نواة الموجّه نفسه — المقارَن الوحيد المتاح على ذلك العتاد على أساس مثل بمثل، لأنه البديل الوحيد المتوفر داخل RouterOS نفسه. مولّدان، لأن لا شيء يعبر التطبيقات بنظافة: dd | nc لتشغيل حاويتنا، و bandwidth-test الخاص بـRouterOS نفسه لتشغيل النواة — يحمل كل منهما سقفه الخاص بلا نفق كضابط، بحيث يمكن للقارئ التحقق من معقولية السقف قبل الوثوق بالنسبة.

المختبر — أربعة أجهزة ضيف Debian بمعمارية aarch64 تحت QEMU/HVF على مضيف واحد بمعالج Apple، بتاريخ 2026-08-31. أزواج المفاتيح والعناوين والمنافذ وMTU وإقلاع الواجهة نفسها عبر كل ملف تنفيذي قيد الاختبار: نواتنا، وboringtun 0.7 (نواة مساحة المستخدم التي فُرّعت منها نواتنا)، و wireguard-go (تطبيق WireGuard-protocol المرجعي، في مساحة المستخدم)، ووحدة WireGuard-protocol الخاصة بنواة Linux نفسها. تشغيلات iperf3 لمدة 15 ثانية، بثلاث عينات لكل حالة، وكلتا نواتَي Rust مُثبَّتتان على خيط معالجة بيانات واحد للسبب المذكور في الملاحظة أعلاه.

task test:impls    # lab: ours vs boringtun vs wireguard-go vs the kernel
task test:all      # lab: single-hop, multi-hop, and the comparison

تشغيل الموجّه ليس هدف task بعد — إنه fv يُشغَّل يدويًا داخل حاوية RouterOS على كل جهاز، مقابل خادم WireGuard-protocol المدمج في RouterOS. تقع الطوبولوجيا الكاملة وكل صف خام في docs/benchmarks/results.csv الخاص بنا.

الرقم المهم: على الموجّه

المقياسنواتنا (مساحة مستخدم)نفق النواة الخاص بالموجّه نفسه
الإنتاجية122 ميغابت/ثانية66.8 ميغابت/ثانية
المعالج، المُرسل65% (63–67)74% (70–79)
المعالج، المُستقبل18% (10–22)20% (18–21)
المعالج لكل ميغابت0.53 %/ميغابت1.10 %/ميغابت
زمن الذهاب والإياب (RTT)1.22 مللي ثانية0.92 مللي ثانية
الذاكرة المقيمة (مُرسل / مُستقبل)3.0 / 3.1 ميغابايتضمن النواة، غير قابلة للفصل
المولّدdd | ncbandwidth-test
سقف ذلك المولّد بلا نفق187 ميغابت/ثانية220.5 ميغابت/ثانية
المحتفَظ به مقابل سقفه الخاص65%30%
نواتنا122 ميغابت/ثانيةنفق نواة الموجّه66.8 ميغابت/ثانية

طول الشريط يتناسب مع ميغابت/ثانية، المحور 0–140. المُرسل RB3011 نفسه في كلا التشغيلين؛ سقف المعالج هو العائق طوال الوقت، بين 65 و79%، بينما يخمل المُستقبل cAP ax عند نحو 20%.

يتفق تأطيران مستقلان، وهذا ما يجعل النتيجة قابلة للتصديق بدلًا من مُنتقاة بعناية: تفضّل الإنتاجية المطلقة نواتنا بـ1.8×، وتفضّلها الإنتاجية المحتفَظ بها مقابل السقف غير المتنازَع عليه لكل مولّد بـ2.2×. ما لا يقوله الجدول: المولّدان ليسا الأداة نفسها، وهذا سبب طباعة كلا سقفَي بلا نفق بدلًا من نسبة عنوان واحدة، وكلا الرقمين سيتحركان لو كان المُرسل يستقبل حركة مرور شبكة حقيقية بدلًا من توليدها محليًا. خلافًا لجدول المختبر أدناه، هذه تشغيلات مفردة: النسب المئوية بين قوسين هي المدى الذي تجوّل فيه المعالج خلال ذلك التشغيل، لا انتشارًا عبر محاولات متكررة.

المختبر: ثلاث نوى في مساحة المستخدم، ونواة واحدة، بخيوط معادلة

النواةالنوعTCP ميغابت/ثانية (المدى، n=3)ذروة الذاكرةزمن الوصول p99
نواتنا، خيط واحدمساحة مستخدم، Rust1535 (1506–1554)3.5 ميغابايت0.94 مللي ثانية
boringtun، خيط واحدمساحة مستخدم، Rust1427 (1346–1479)5.3 ميغابايت1.15 مللي ثانية
wireguard-go، الإعداد الافتراضيمساحة مستخدم، Go1228 (1221–1239)34.8 ميغابايت1.39 مللي ثانية
WireGuard في النواة، الإعداد الافتراضينواة، C1376 (1366–1386)— (ضمن النواة، غير قابلة للفصل)0.96 مللي ثانية

كما شُحن، من دون معادلة: نواتنا تعمل افتراضيًا بخيط واحد وسجّلت 1535 ميغابت/ثانية؛ أما boringtun فيعمل افتراضيًا بأربعة خيوط وسجّل ~789 ميغابت/ثانية بذلك الإعداد. الإبلاغ عن رقم الإعداد الافتراضي مقابل الافتراضي فقط كان سيكرر الخطأ نفسه في الاتجاه المُجامِل. كلا الرقمين حقيقي؛ أحدهما فقط يعزل مسار البيانات عن عدد الخيوط.

تكلفة المعالج هي حيث يكسب المختبر مكانه في هذا المقال — إنه المحور الوحيد الذي لا يستطيع جدول الموجّه إظهاره، لأن مقارَن الموجّه المدمج في النواة لا يمنحك أي تفصيل للمعالج تقارن به.

مستخدمنظامنواتنا0.90 ث/غيغابت إجمالًامستخدم 0.347 · نظام 0.549 ث/غيغابتboringtun1.08 ث/غيغابت إجمالًامستخدم 0.290 · نظام 0.787 ث/غيغابتwireguard-go2.37 ث/غيغابت إجمالًامستخدم 0.876 · نظام 1.490 ث/غيغابت

الأقل أفضل. المحور 0–2.5 ث/غيغابت، خطي. يتراكم الجزءان من اليسار إلى اليمين؛ والانقسام هو حيث يظهر فقدان القسم التالي.

نواتنا3.5 ميغابايتboringtun5.3 ميغابايتwireguard-go34.8 ميغابايت

مقياس لوغاريتمي، من 1 إلى 50 ميغابايت، مذكور لأنه ليس الإعداد الافتراضي الصادق: على محور خطي، كانت 34.8 ميغابايت الخاصة بـwireguard-go ستُسطّح الشريطين الآخرين إلى خطوط شعرية.

أين لم نفز

مكانان، كلاهما مشروح لا مدفون في ملف CSV:

معالجة المستخدم (User-mode)، في المختبر. 0.347 ثانية/غيغابت مقابل 0.290 الخاصة بالمقارَن الأرخص المكتوب بـRust — العمود الوحيد في ذلك الجدول الذي يتقدم فيه علينا. قراءتنا هي أن هذا مُشترى، لا مُهدر: تُجري نواتنا إلغاء تحميل التحقق (checksum offload) لواجهة TUN في كلا الاتجاهين، وهو ما ينقل العمل من النواة إلى معالجة مساحة المستخدم المُحتسبة كوقت مستخدم — وعمود معالجة النظام، حيث تُسدَّد تلك المقايضة، متقدم بارتياح (0.549 مقابل 0.787). لا يزال إجمالي المعالجة يفوز. تقسيم مستخدم/نظام أعلاه مُعروض تحديدًا كي تكون هذه المقايضة مرئية بدلًا من مجرد مُدَّعاة.

زمن الذهاب والإياب، على الموجّه. 1.22 مللي ثانية مقابل 0.92 مللي ثانية الخاصة بنفق النواة — المحور الوحيد في العتاد الذي يفوز فيه ما هو داخل النواة تمامًا، للسبب المعتاد وهو أن مسارنا يدفع ثمن قفزة veth لحاوية ودورة جدولة في مساحة المستخدم لا يدفعهما مسار داخل النواة. المثير للاهتمام أن المختبر يُظهر الترتيب المعاكس في زمن الوصول p99 (0.94 مللي ثانية مقابل 0.96 مللي ثانية للنواة) — لا نقرأ في ذلك أكثر من "بيئات مختلفة، واختناقات مختلفة"، ونقول ذلك بدلًا من اختيار أي رقم يُجامل أكثر.

ما هو جديد وما هو موروث

يحمل كل رقم أعلاه تاريخًا، والتواريخ مهمة: جدول الموجّه بتاريخ 2026-09-01، وجدول المختبر بتاريخ 2026-08-31. منذ ذلك الحين، نقلت ترقية إصدار رئيسية منسّقة صناديق التشفير الأساسية التي تستدعيها طبقة بياناتنا في كل حزمة — chacha20poly1305، وblake2، وcurve25519-dalek — ولم نُعِد تشغيل مقارنة المختبر أو الموجّه الكاملة مقابل تلك الشجرة بعد. الأرقام أعلاه حقيقية وقِيست بعناية، لكن عمرها ستة أيام وقت النشر، على شجرة تسبق تلك الترقية. ننشرها مع ذكر ذلك بدلًا من الصمت، وسنؤرخ إعادة تشغيل عندما تتوفر لدينا واحدة. رقم الموجّه أيضًا غير مثبّت على التزام (commit) محدد في سجلاتنا الخاصة — اقرأ "2026-09-01" على أنها "أوائل سبتمبر"، لا مرتبطة بتغيير تحسين واحد.

ما يمكننا إعادة تشغيله اليوم، على هذا الجهاز، من دون موجّه أو مختبر أجهزة افتراضية، هو الجزء من المسار الذي لامسته ترقية التشفير بشكل مباشر أكثر: تكلفة التغليف وفك التغليف (encapsulate/ decapsulate)، معزولة عن أي مقبس أو TUN أو مخاوف خيوط أعلاه.

العملية، حجم الحزمةنواتناboringtun 0.7.1
تغليف، 64 بايت219.2 نانوثانية218.7 نانوثانية
تغليف، 512 بايت436.4 نانوثانية442.5 نانوثانية
تغليف، 1420 بايت938.1 نانوثانية968.3 نانوثانية
فك تغليف، 64 بايت238.8 نانوثانية226.7 نانوثانية
فك تغليف، 512 بايت562.1 نانوثانية539.2 نانوثانية
فك تغليف، 1420 بايت1099.5 نانوثانية1069.4 نانوثانية

أُعيد التشغيل بتاريخ 2026-09-05، على Apple M3 Max، بواسطة cargo bench -p forestvpn-quantum --bench datapath_benches -- --measurement-time 3 --warm-up-time 1، وcriterion 0.8.2، بـ100 عينة لكل نقطة. لا مقبس، ولا TUN، ولا خيوط — مصافحة واحدة مكتملة، ثم تغليف/ فك تغليف في حلقة. النتائج متفاوتة حسب الاتجاه وحجم الحزمة، كلها ضمن نسبة مئوية قليلة في أي اتجاه، وهو تمامًا ما نتوقعه: تفرّعت نواتنا من هذا المسار من مصدرها الأعلى (upstream)، وكلتاهما تقفان الآن على الجيل نفسه من بدائيات RustCrypto. هذا ليس ادعاء إنتاجية — إنه يقول إن مسار التشفير المُفرَّع نفسه يكلّف تقريبًا ما يكلّفه مصدره الأعلى، ضمن هامش الضجيج، وهو ما يجعل انتصارات المختبر والموجّه أعلاه جديرة بالثقة: فهي تأتي من مكان آخر في المكدّس (تجميع استدعاءات النظام، والتفريغ، والخيوط)، لا من مُشفِّر أسرع.

إعادة الإنتاج

task test:impls          # lab: ours vs boringtun vs wireguard-go vs the kernel
task test:all            # lab: single-hop, multi-hop, and the multihop cost table
cargo bench -p forestvpn-quantum --bench datapath_benches -- --measurement-time 3 --warm-up-time 1

تشغيل الموجّه يدوي اليوم: fv داخل حاوية RouterOS على كل جهاز، مقابل خادم WireGuard-protocol الخاص بـRouterOS نفسه.

لنكن صريحين حول ما يمنحك إياه ذلك: يعيش السجل الفعلي وملف results.csv الخام خلف كل جدول هنا في شجرتنا، وهي ليست عامة اليوم. اقرأ الأوامر أعلاه كبيان دقيق لما شغّلناه، لا كشيء يمكنك استنساخه وتكراره. الادعاء الأقل اعتمادًا علينا هو أيضًا الأكثر جدارة بالتحقق — boringtun وwireguard-go علنيان، وiperf3 علني أيضًا، وفخ عدد الخيوط في أعلى هذا المقال (علامة واحدة تُحرّك مقارَنًا بين نحو 789 و1427 ميغابت/ثانية على مضيف واحد) قابل للتكرار من أي شخص يملك هذه الثلاثة من دون أي من شيفرتنا في الحلقة. إذا صمد الأمر بالنسبة لك، فالصفوف المُعادَلة أعلاه هي التي يجب مناقشتها. إذا لم يصمد، نريد أن نسمع عن ذلك.

كل المقالات

العربية
اسألنا أي شيء