← العودة إلى المقالاتاكتشافSeptember 19, 20269 د قراءةCopy article

Kitsune2: البحث أسرع بـ 251 مرة، مسار التحديث بـ 33 مرة، والحديث بدأ بـ 15 مرة أبكر

في صباحٍ من التجارب على طبقة الشبكات في Holochain: كيف تجد العقد الأقران، تجلب البيانات المفقودة، وتستأنف الحديث، وما الذي غيره 6 التصحيحات الصغيرة على طول الطريق.

Developed by Robert E. Beckner III (Merlin) | rbeckner.com

لقد كنت أستيقظ حول 4:30 صباحًا مؤخرًا، قبل شروق الشمس، وأستمتع بذلك. في 19 سبتمبر استخدمت ذلك الصباح لبدء مختبر على Kitsune2، طبقة الشبكات peer-to-peer تحت Holochain، وذهبت للبحث عن أين يقضي الوقت.بحلول 12:20 مساءً، أنتج المختبر 6 تصحيحات. بحث النقاط النهاية: 251× أسرع عند 10,000 هويات محفوظة. مسار التحديث peer الذي يستدعيها: 33× أسرع. بدء الحديث بعد جلب مكتمل: 3,002 مللي ثانية إلى 202 مللي ثانية. حركة طلبات الارتداد: 96.9% رسائل أقل. 3 من التغييرات التي أصلحت عملًا كان ينتظر بلا داعٍ، أو ينتظر شيئًا لن يحدث أبدًا.لقد كنت أبرمج لأكثر من 25 سنوات وأبني مع AI منذ GPT-3. أستخدمه لعزل شيء يهمني أو لا أفهمه بعد، أعمل عليه، وأختبر ما نعتقد أننا تعلمناه. أحب ذلك الجزء: تحويل سؤال إلى تجربة ورؤية ما يظل صحيحًا. هذا الصباح، مع وكلاء برمجة AI، طبقت ذلك النهج على الآلية التي تسمح لعقد Holochain بالحفاظ على بعضها البعض محدثًا.يشارك تطبيقات Holochain البيانات عبر الحواسيب المشاركة، أو العقد. يحتفظ كل مشارك بتاريخاته الموقعة الخاصة به ويساعد في التحقق وتخزين جزء من بيانات التطبيق المشتركة. هذا المخزن المشترك هو جدول التجزئة الموزع، أو DHT. تُحفظ النسخ مع عدة أقران، لذا يمكن أن يظل البيانات متاحة عندما يخرج مؤلفها من الخطأ. Holochain's DHT دليل يشرح كيف يتم توزيع تلك المسؤوليات.Kitsune2 يدير الاتصال بين الأقران تحت هذا. تخيل عقدة تتعقب: تتعلم أين يمكن الوصول إلى الأقران، تقارن ما تحتفظ به مع ما يملكه الآخرون، وتطلب القطع التي تفتقدها. الثرثرة هي التبادل الذي يكتشف الأقران تلك الاختلافات؛ الاسترجاع يسترجع العمليات المفقودة، وحدات البيانات التي ينقلها Kitsune 2. تُعطي العقدة المستقبلة هذه إلى مخزن عمليات المضيف الخاص بها. يتعامل Holochain مع التحقق والتكامل لها.
Diagram source
graph TD
    A[تعلم هوية الأقران ونقاط النهاية] --> B[قارن البيانات عبر التثرثرة]
    B --> C[حدد العمليات المفقودة]
    C --> D[استرجع العمليات من الأقران]
    D --> E[سلم العمليات المستلمة إلى مخزن المضيف]
    E --> F[إشارة إلى أن الاسترجاعات المعلقة قد اكتملت]
    F e1@--> B
    e1@{ animation: fast }
Copy source
البقع تجلس على تلك التسلسل. بعضهم يقلل العمل الذي تقوم به العقدة؛ آخرون يتركها تتقدم عندما ينتهي العمل بالفعل. الأرقام أعلاه تقيس تلك الخطوات الخاصة على عقد الاختبار المحلية.

ما الذي حرك كل من تغييرات 6 فعليًا#

أصلحنا نقطة البداية عند الالتزام الأعلى 06555ee, مصدر التطوير 0.6.0-dev.1. كل مقارنة تستخدم ذلك الأساس بالإضافة إلى تسلسل التصحيح المسجل. العلامات أدناه تربط النتائج بسجلات تجربتنا؛ جميع تصحيحات 6 الآن مُقدَّمة للمراجعة العليا.
علامةما تغيرالنتيجة المقاسة
K3aاستدعاء مساعدة التصريف الحالية عند اكتمال جلببدء الجدل بعد جلب مكتمل: 3,002 → 202 مللي ثانية
K3bقفل المستقبل محدد بالانقضاءكان التزامن الفعّال 1. العمال المُكوَّنون الآن يتداخلون فعليًا
K3cملكية الدخول الموسومة بالتوليدتم إلغاء خيط المتصلين 0 المفاتيح المعلقة. القاعدة المعلقة 8
K3d-P1تنظيف استجابة قائمة على المجموعة1.9–6.1× معالجة استجابة أسرع عند أحمال معلقة كبيرة
K3d-P2اختيار تجميع الأقران نفسه (افتراضي 1)النبضات: 87.5–96.9% رسائل طلب أقل
K1عكس URL إلى فهرس الوكيلعند 10,000 هويات محفوظة: تحديثات 21–33×، عمليات بحث 118–251× أسرع، لتخزين الذاكرة 3.10×
الإصلاح الأول يعيد ربط إكمال الجلب بمهمة الدردشة المنتظرة لها. التغيير يستدعي مساعدة موجودة تخبر المستمعين أن خريطة الانتظار قد امتلأت. اختبرنا كل من جلب مكتمل وجلب مفتوح عمدًا.
Gossip initiation after a fetch completes, with the control that must not move (ms)
Chart datamilliseconds
Upstream 06555eeWith the drain notification restored
Fetch completed3001202
Fetch still pending (control)30023001
بعد الإكمال، يمكن أن تستمر الدردشة. بينما يبقى الجلب معلقًا، لا تزال النسختان تصلان إلى مؤقت الاستبدال. الاختبار المعزول أعلاه قياس 3,001 → 202 مللي ثانية؛ إعادة التشغيل المجمعة لاحقًا قياس 3,002 → 202 مللي ثانية. كلاهما استخدم fallback بـ 3,000 مللي ثانية وتأخير أولي بـ 200 مللي ثانية. الفرق تقريبًا 15× يسجل أي مسار اتخذته المهمة: الانتظار للfallback أو الاستيقاظ عند الإكمال.

كل تغيير يعيش في حزمة واحدة، و5 من 6 في ملف واحد#

حزمة Rust هي حزمة من الكود. جميع تصحيحات 6 تعيش في الحزمة الأساسية، التي تحتوي على سجلات الأقران وآلية الجلب. تغيرون كيف يحصل الغوس على بياناته وإشارات الاكتمال دون تعديل خوارزمية الغوس أو النقل الشبكي الأساسي. التجميع يضيف حقل تكوين أساسي اختياري.
التسميةالملفالأسطر
K1core/src/factories/core_known_peers.rs+33 / −10
K3acore/src/factories/core_fetch.rs+1
ك3بcore/src/factories/core_fetch.rs+11 / −3
ك3جcore/src/factories/core_fetch.rs+71 / −53
ك3د-ب1core/src/factories/core_fetch.rs+6 / −1
ك3د-ب2core/src/factories/core_fetch.rs، ملف اختبار واحد+89 / −17
5 تصحيحات مكدسة بترتيب مسجل على core_fetch.rs، الذي يطلب العمليات المفقودة ويعالج الاستجابات. يبقى التصحيح المتبقي في core_known_peers.rs، السجل المحفوظ الذي يربط هويّة معينة بنقطة نهاية شبكة معينة. ثم طبقنا جميع 6 على شجرة مصدر واحدة ونفذناها معًا.

وصلت البيانات، لكن الجدل ما زال ينتظر#

CoreFetch يحافظ على خريطة للعمليات التي طلبها ومن من. عندما يصل رد الأقران وتُخزن العمليات بنجاح، يزيل الكود تلك المعرفات من الخريطة. أجزاء أخرى من الملف، مسار إرسال الخطأ ومسار تنظيف الأقران، تستدعي مساعدة تُدعى notify_listeners_if_queue_drained مباشرة بعد إزالة الإدخالات. لم يُستدعِ مسار النجاح أبدًا.يمكن للعنقود توسيع الجزء من DHT الذي يخزنه، يُسمى قوس التخزين. للقيام بذلك، يحتاج إلى اللحاق بالبيانات داخل النطاق الأكبر. في مسار نمو القوس الذي اختبرناه، ينتظر الجدل للإنهاء الجلب المعلق قبل البدء مع أقران، مع مؤقت كخيار بديل. وصلت البيانات وتفرغت الخريطة المعلقة، لكن المهمة التي تنتظر ذلك الإشارة بقيت نائمة حتى انتهى المؤقت.
Diagram source
sequenceDiagram
    participant G as Gossip arc-growth loop
    participant F as CoreFetch
    participant P as Peer
    G->>F: Register a drain waiter
    P->>F: Final response, operations stored
    F->>F: retain() empties the pending map
    Note over F: helper exists, never called
    F--xG: Notification that never arrives
    G->>G: Initiate after the roughly 3-second fallback
Copy source
التحقق بعد الاكتمال يخفي الفرق: ينتظر مسجل جديد يرى الخريطة الفارغة ويعود فورًا. سجلنا أُسْتُرْنَا قبل الاكتمال. بمجرد تخزين البيانات، ما زال ذلك النادل لا يملك إشعارًا على الكود الأصلي؛ مع التصحيح، تلقى واحدًا. هذا يصلح الانتقال بين استلام البيانات وبدء تبادل الجسوس التالي.كما فحصنا الردود الجزئية، أخطاء المتجر، عدة مستمعين، ومستمعين يسجلون كطلبات مكتملة أو عمل جديد قد وصل. يجب أن يترك الرد الجزئي النادل في الانتظار؛ فقط إكمال الجلب النهائي المتبقي يجب أن يوقظه.

تم تكوين 5 العمال، و1 كان يرسل فعليًا#

الجهة الصادرة من CoreFetch تشغل عددًا مُكوَّنًا من مهام العمال التي تستخرج من قناة مشتركة واحدة. كُتِب الحلقة هكذا:rustCopy source
while let Some(..) = outgoing_request_rx.lock().await.recv().await {    // send the request}
يتيح القفل لـ1 العامل أخذ الطلب التالي من قائمة الانتظار المشتركة. لكن Rust يحافظ على حارس القفل المؤقت حيًا طوال جسم هذا while let، بما في ذلك الانتظار لإرسال الشبكة. بينما كان 1 العامل يرسل، لم يتمكن 4 الآخر حتى من جمع طلبه التالي. ما زالت جميع الطلبات يمكن أن تصل في النهاية، لذا يمكن أن ينجح اختبار التسليم بينما لم يُستخدم التزامن المُكوَّن.نقلنا الاستقبال إلى كتلة قصيرة حتى يُطلق القفل قبل بدء الإرسال. لا يزال العمال يتناوبون على جمع الطلبات، ثم يرسلونها بالتوازي. لا يظل إرسال بطيء القفل في قائمة الانتظار بينما العمال الآخرين لديهم طلبات جاهزة.
Outgoing sends in flight at the same moment, by configured worker count
Chart dataconcurrent sends observed
Upstream 06555eeDequeue-scoped guard
1 worker11
2 workers12
5 workers15
يحتفظ القياس بكل إرسال مفتوح مع ساعة متوقفة ويعد عددًا من الذين دخلوا قبل أن يُطلق أي منها، ثم يؤكد أنه لا يدخل أي شيء يتجاوز الحد المُكوَّن.

إلغاء مكالمة ترك العقدة في انتظار عمليات غير مرسلة لـ8#

يمر طلب الجلب عبر سجلات 2: تقول الخريطة المعلقة ما تنتظره العقدة، وتحتفظ قائمة الانتظار الصادرة بالعمل للعمال المرسلين. request_ops، الطريقة التي تطلب العمليات، أضاف دفعة كاملة إلى الخريطة المعلقة قبل الانتظار للفراغ في تلك القائمة.إذا تم إلغاء المكالمة أثناء انتظار السعة، فقد تم وضع بعض العمليات بالفعل في وضع المعلقة رغم عدم استلام أي عامل لها. ملأنا القائمة، ألغينا مكالمة محظورة، ودعنا جميع الطلبات المقبولة لـ16,385 تُكمل. بقيت عمليات 8 معلقة. لم تدخل أبدًا القائمة الصادرة، لذا لم يكن هناك رد في طريقه لمسحها.هذا يتصل مباشرة بالإصلاح الأول: لا يمكن إشعار الإكمال أثناء احتواء الخريطة على عمل غير مكتمل. هنا، كان حساب العقدة الخاص بها يحافظ عليها في الانتظار.يحجز التصحيح سعة القائمة أولاً، ثم يسجل ويضيف العملية إلى القائمة دون انتظار آخر بين هذين الخطوتين. كل إدخال يحمل أيضًا علامة جيل، لذا لا يمكن لتنظيف إرسال فاشل قديم مسح طلب أحدث لنفس العملية. يبقى العمل المقبول بالفعل بعد إلغاء المكالمة؛ لا يترك العمل الذي لا يزال في انتظار القبول إدخالًا معلّقًا خلفه.هذا يصلح ملكية الطلبات. لا تزال حدود الذاكرة الإجمالية مسألة تصميم منفصلة، لأن المكالمة لا تزال يمكن أن تُقدّم دفعة كبيرة.

رسائل طلب أقل، مع حد على مدى حجم كل منها#

قد يحتاج عقدة متعقب إلى العديد من العمليات من نفس النظير. تنسيق طلب Kitsune2 يدعم بالفعل قائمة من المعرفات، لكن الكود الصادر يرسل 1 لكل رسالة. قبل دمج تلك الطلبات، تحققنا من كيفية معالجة الردود الأكبر.لكل عملية معلقة، فحص تنظيف الرد القائمة على معرفات المردود لمعرفة ما إذا كان يمكن إزالة ذلك الإدخال. مع 8,192 إدخالات معلقة و1,024 معرفات مردودة، يتكرر ذلك بحثًا كبيرًا. بناء HashSet من المعرفات المردودة يجعل كل فحص عضوية رخيصًا؛ قياس معالجة الرد 6.1× أسرع في تلك الحالة. مع فقط 16 معرفات مردودة، سيطرت تخزين البيانات على الأداء ولم يحقق التغيير الكثير.ثم دمجنا الطلبات الجاهزة لنفس النظير. في انفجار من 64 عمليات صغيرة، أحجام الدفعة من 8 و32 خفضت رسائل الطلب بـ 87.5% و 96.9% على التوالي.
Burst behaviour relative to the default batch size of 1 (percent of control)
Chart datapercent of control
Request messagesElapsed time
Batch 1 (control)100105.4
Batch 812.572.6
Batch 323.167.7
انتهى الانفجار قبل حوالي 27–32% أسرع. ما زالت العمليات نفسها يجب نقلها وتخزينها؛ التوفير كان في عدد الطلبات التي حملتها. قياس التحكم batch-1 أظهر 105.4% من الوقت المنقضي الأساسي، مع إظهار تقارب توقيت تقارب 5% حتى مع عدم تفعيل الدفعات.يجمع العامل فقط الطلبات التي جاهزة بالفعل، لذا لا تنتظر طلب وحيد لملء دفعة. يستخدم تقسيم الدفعة حد معرف مكوّن ومقدار 4,096-byte encoded request threshold. عد العناصر وحده لا يقيّد حجمها الإجمالي؛ الاختبار مع 200 معرفات يقسمها إلى رسائل متعددة محدودة. لا يزال يُرسل معرف واحد إذا تجاوز ذلك الحد وحده، لذا هذا ليس حدًا عالميًا لحجم السلك. تحمل الردود البيانات الفعلية وقد تحتاج إلى حد حجم منفصل على العقدة المردودة.يحتفظ المرشح بحجم الدفعة 1 كإعداد افتراضي ويقبل التكوينات الحالية دون تغيير. تركنا خيار الاشتراك في الدفعات الأكبر لأن الاختبار المنفصل لطلب وحيد أنتج نتائج تأخير ذيل غير متسقة، كما هو موضح أدناه.

كان إزالة المسح من مسار التحديث يستحق 33×، و251× على البحث نفسه#

CoreKnownPeers يتذكر الهويات ونقاط النهاية الشبكية المرتبطة بها. يمكن لعدة هويات أن تشترك في نقطة نهاية، ولا تزال الهوية المحظورة بحاجة إلى أن تكون قابلة للتحديد بعد إزالتها من مخزن النظير النشط. 10,000 هويات محفوظة تعني بالتالي تاريخ هويات في هذا المخزن، وليس 10,000 أجهزة كمبيوتر متصلة في وقت واحد.عند تحديث مخزن النظير، يطلب التحكم بالوصول أي هويات تنتمي إلى نقطة النهاية. البحث، get_by_url، فحص الخريطة المحفوظة بالكامل تحت قفل في كل مرة. مع نمو هذا التاريخ، أصبح تحديث معلومات النظير الحالية أكثر تكلفة.أضفنا فهرسًا من نقطة النهاية URL إلى الهويات المرتبطة بها: HashMap<Url, HashSet<AgentId>>`. تبقى السجلات الأصلية ذات سلطة. عندما تتغير الهوية نقطة النهاية، ينقل الفهرسها إلى المجموعة المقابلة؛ يمكن للبحث بعد ذلك الذهاب مباشرة إلى تلك المجموعة. مرت كل النسخ 19,422 فحوصات النتيجة التي تغطي التحديثات، الإعلانات القديمة، الإزالة، والنقاط النهائية المشتركة.
Microseconds per 16-advertisement update call (log scale)
Chart datamicroseconds per update call
retained identitiesUpstream linear scanDerived URL index
1006.8574.911
1,00018.1034.774
10,000154.8494.72
كل مكالمة مؤقتة أعلاه تُدرج 16 إعلانات وتدير مستمعي التحكم بالوصول. عند 10,000 هويات محفوظة، انخفضت من حوالي 155 µs إلى 4.72 µs، مكسب مزدوج 33×. تبقى النسخة المفهرسة شبه مسطحة عبر هذه الأحجام لأن المستمعين لم يعودوا يفحصون التاريخ المتزايد.مقاسة عند API بدلاً من عبر المُستدعي، يذهب البحث نفسه من مسح إلى تجزئة. فشل عند 10,000 هويات محفوظة انخفض من 11,423 ns إلى 45 ns، مكسب مزدوج 251×، وفشل واحد من 9,309 ns إلى 79 ns، 118×. استعلام يُعيد العديد من الهويات لا يزال يتسع بما يُعيده، لذا يحصل حالة shared-URL على 4.4× بدلاً من 2 ترتيبًا للدرجة. 251× هو نتيجة البحث المعزولة. 33× يقيس مكالمة التحديث الأكبر التي تستخدمه؛ لا يمكن إضافة هذه المكاسب أو ضربها.
Requested store memory at 10,000 retained identities, by endpoint shape
Chart datamegabytes
UpstreamWith the index
Mixed endpoints1.23.71
All shared1.21.74
All URL-less1.21.2
3.10× في متجر مختلط، إضافة 2.51 ميجابايت عند 10,000 هويات. عندما تشترك كل هوية في نقطة نهاية، يكون الخريطة المشتقة صغيرة وتقل التكلفة إلى 1.45×. عندما لا توجد هوية لها URL لا يوجد شيء لتشتق منه والتكلفة صفر. هذه الأرقام هي بايتات يطلبها المخصص للمخزن المحفوظ، وليست الذاكرة الكلية للعنصر.

مع جميع تصحيحات 6 معًا، كان بإمكان العقدة الانتهاء والاستمرار#

استخدم إعادة التشغيل المجمعة حوار Kitsune2 الحقيقي، والاسترجاع، والوصول إلى الأقران، ومكونات مخزن الذاكرة، مع التواصل عبر ناقل الاختبار في الذاكرة. أجرينا تسلسلًا خطوة 5 على الأشجار المصدرية الأصلية والمصححة:
  1. تحديث معلومات الأقران. تتغير الهوية نقطة النهاية. تبقى المعلومات القديمة التي تصل لاحقًا السجل الأحدث سليماً، وتظل الهوية المحظورة قابلة للحل للتحكم بالوصول. يمر كلا الإصدارين؛ يحافظ الفهرس على القرارات الحالية.
  2. بدء الحوار بعد اكتمال الاسترجاع. يبدأ العقدة المصححة بعد 202 مللي ثانية. الأصل يتخذ مسار الاستبدال عند 3,002 مللي ثانية.
  3. استقبال البيانات خارج الترتيب. تصل العمليات المطلوبة 3 كإجابات 4، بما في ذلك نسخة مكررة. يخزن كلا الإصدارينها بشكل متسق ويربط عدد البايتات بالعملية الصحيحة.
  4. إنهاء الاسترجاع. يمكن استرجاع العمليات المخزنة. كما تستيقظ العقدة المصححة المستمع الذي سجل أثناء انتظار تلك العمليات.
  5. الاستمرار بعد فشل عُنق. يفرغ فشل الإرسال المسيطر حالة طلب العُنق. يقدّم عُنق آخر العملية، وتفرغ الخريطة المعلقة، وينجح استرجاع لاحق. في الأصل، تفشل فحوصات إشعار الاكتمال.
اختبارات التفاعل المنفصلة جمعت الإلغاء مع الإرسال المتزامن وتجميع الدفعات مع إشعار الاكتمال. احتفظت الإصلاحات معًا: تم إكمال العمل المقبول، ولم تُترك إدخالات أيتية بعد الإلغاء، واستيقظ المستمعون بعد الاستجابة النهائية.هذا يوصينا إلى أن البيانات المستلمة في مخزن المضيف والخطوة الشبكية التالية يمكن أن تتقدم. لا تزال عملية التحقق والتكامل في Holochain تتبع خارج هذا المختبر. لم نقم بعد بقياس مدى تقصير هذه التغييرات لوقت التحديث الكامل لعقد حقيقي.

ما يكلف كل مكسب#

تكلفة الفهرس للذاكرة وتزيد تكلفة تغييرات نقطة النهاية. في اختبار المخزن الصغير الأصلي، كان تحديث مجموعة ثابتة من الهويات إلى عناوين URL جديدة يعمل بسرعة 0.946× مع هويات 100 محفوظة. عند 10,000، كان تكلفة كتابة تغيير نقطة النهاية المعزولة 3.68× أكثر. الحفاظ على الفهرس الإضافي له ثمن؛ يجب أن تعود وفورات البحث لتسديده.لأن هذا التوازن حقيقي، بحثنا عن عبء العمل حيث يفقد الفهرس. 36 التكوينات تم إعلانها مسبقًا قبل القياس، 432 الجولات المزدوجة تم تنفيذها، والنسخ المقتبسة للنتيجة تم تجزئتها بشكل متطابق بين المتغيرات.
Paired speedup across the 36-config workload envelope, by mix (log scale)
Chart datapaired speedup
retained identitiesSteady, no rebind100% rebindShared endpointsURL-less heavy
1001.611.471.421.09
1,0007.26.264.122.13
10,00055.5636.425.5512.16

Reference line, parity: 1

كان لكل عبء عمل في هذه المصفوفة الأوسع متوسط أعلى من التكافؤ، بما في ذلك المزيج حيث كل تحديث مقبول يغيّر نقطة النهاية: 1.47× عند 100 هويات و36.42× عند 10,000. هذه التحديثات أيضًا تحفز عمليات البحث للتحكم في الوصول، وكانت وفوراتها تفوق الكتابات الإضافية. يختلف عبء العمل الأوسع عن الاختبار الثابت السابق؛ نتيجته الإيجابية تترك الانحدار الصغير في السجل.الحالة ذات الـ100 هوية، معظمها URL-less لا تزال غير حاسمة: متوسطها 1.09× شمل نتيجة مزدوجة أقل من التكافؤ. لا يزال نحتاج إلى تتبع من العقد الحقيقية تُظهر عدد الهويات المحفوظة، تغييرات نقطة النهاية، وتواتر البحث قبل التوصية بالفهرس لعبء عمل معين.الإرسال المتزامن كشف تفاعل تنظيف. عندما يمكن للعمال التداخل، يمكن أن يعمل تنظيف إرسال فاشل أثناء وجود طلب آخر إلى نفس القريب في الطيران. جعل ذلك تنظيف القريب العام أوسع من العمل الذي فشل. حدّدت تصحيح الملكية إزالة الإدخالات التي لا تزال تنتمي لتوليد الطلب ذلك. اختبار التصحيحات معًا كان مهمًا هنا.زمن الانتظار للطلب الوحيد في التجميع لا يزال غير حاسم. قياسنا p95، الوقت الذي تنتهي فيه 95% من الطلبات. لطلب يُرسل بمفرده، أظهر تشغيل العامل النهائي 1.01–1.08× سرعة p95 الأساسية؛ أظهر إعادة التشغيل المستقلة 1.44–1.58×. تستغرق هذه التركيبات عشرات الميكروثانية، كما ان تحكمها أيضًا انحرفت. تم إعادة إنتاج تحسين النشوة، لكن نتيجة الطلب الوحيد لم تستقر، لذا تبقى الدُفعات الأكبر اختيارية.

المقارنات المتكررة وإرسالات متوقفة لا تزال مفتوحة#

كما فحصنا 2 أجزاء أخرى من نفس تسلسل اللحاق. لم ينتج أي منهما تصحيح مقبول.مقارنة ما يملكه الأقران بالفعل (K4). يستخدم الغوس ملخصات مضغوطة للبيانات المخزنة لإيجاد الاختلافات. في أكبر اختبار، إنتاج ومقارنة لقطة غير متغيرة مَجَسَّم 262,144 تجزئات؛ تكرارها 10 مرات أنتج مخرجات متطابقة في كل مرة. إعادة استخدام ملخص سابق يبدو جذابًا، لكن مخزن المضيف قد يتغير دون إشارة موثوقة لإبطال ذلك النتيجة المحفوظة. قد يخفي ملخص مخزن ثمّ اختلافًا بين الأقران. كما أن البدائل التي قيمناها لم تُحقق الوقت المطلوب 20% في مخزن الذاكرة. القياسات من مخزن Holochain حقيقي هي القطعة المفقودة التالية.التعافي عندما يتوقف إرسال الغوس (K2). رفع قراءة المصدر سؤالًا حول إرسال يحمل قفلًا يحتاج إليه مهمة المهلة أيضًا. كنا بحاجة أيضًا إلى تحديد ما يحدث لتدفق نقل Iroh الأساسي إذا تم إلغاء ذلك الإرسال في منتصف الطريق. حظر موفر الوكيل عملًا على محرك إعادة الإنتاج، لذلك لم يُكمل اختبار التشغيل. لا يزال هذا قلقًا غير مختبر، دون تصحيح أو نتيجة موثوقية.

ما قياسناه، وما يزال يُقاس#

أجريت هذه التجارب على مصدر التطوير 0.6.0-dev.1، على جهاز Apple M4 Max مشترك واحد مع 16 نواة منطقية. استخدمنا عقد اختبار محلية ونقلات في الذاكرة، دون تثبيت النواة أو مضيف مادي ثاني. تغطي النتائج المكوّنات المسماة وتفاعلاتها. لا تزال سرعة الشبكة، وتقارب الشبكة الكاملة، وذاكرة العقد الكلية، وتأخير تطبيق Holochain غير مقاسة.تتبع الطريقة عملي على benchmark-driven development. سجلنا كل سؤال وعتبة القبول، وثبّطنا المصدر والملحقات داخل كل مقارنة، وحافظنا على الأوامر والعينات والفشل في إيصالات مضافة فقط.بالنسبة لإصلاحات 3، فشل نفس الاختبارات على الكود الأصلي عند التأكيدات المتوقعة ونجحت مع التصحيح. بالنسبة للتحسينات، كان على كلا الإصدارين الحفاظ على السلوك، ثم كان على القياسات أن تحقق العتبة المذكورة. بدّل تشغيلات التوقيت ترتيبها وحافظ على التجميع خارج نافذة القياس. أعد وكيل إشرافي تشغيل أوامر القبول على المصدر المجمد قبل قبول كل نتيجة؛ ظل الخلاف حول تأخير الطلب الوحيد في التقرير النهائي.يحتوي الحزمة المكتملة على أدلة إيصالات 204. تم قبول الاختبارات المجمعة في 12:17 ظهرًا، وتُسجّلت النتائج النهائية في 12:20 ظهرًا. تم الاحتفاظ بفحص الإغلاق النهائي في 2:38 ظهرًا. جميع الـ6 تصحيحات مفتوحة الآن للمراجعة العليا: completion notification, worker concurrency, admission ownership, response cleanup, request batching, و endpoint indexing.

التقديرات الرئيسية#

بواسطة أنا. المختبر نفسه: طريقتي المدفوعة بالمعايير، موجهة نحو Kitsune2 للعثور على أين كان يقضي الوقت.بواسطة GPT-6 Astra. إصلاحات إشعار الإكمال وملكية القبول: التشخيص، التصحيح، والاختبارات التي تفشل على الكود الأصلي. كما صقّرت هذا المقال من سجلات المختبر.بواسطة GLM-5.3. إصلاح تزامن العمال، تنظيف الاستجابة والتجميع، مصفوفة عبء العمل 36-configuration للفهارس، تحليل ملخص DHT خلف سؤال K4 المفتوح، وإعادة تشغيل مجتمعة لجميع 6 التصحيحات.بواسطة AI. فهرس النهاية وقياساته، وكائن إشرافي أعاد تشغيل كل قبول على المصدر المجمد قبل أن يُحسب النتيجة، والمسودة الأولى لهذا المقال.الانتقادات التي بقيت.وصلنا معًا. تسلسل اللحاق الذي يتبعه المقال: يتعلم العقدة أقرانها، يقارن ما يملكه، يجلب ما يفتقده، يخزنه، ويستمر، مع وضع كل تصحيح عند الخطوة التي يغيّرها.بناءً على. مصانع المكوّن القابلة للاستبدال لفريق Holochain الأساسي والنقل في الذاكرة، التي سمحت للمختبر باختبار هذه السلوكيات في مكوّنات Kitsune2 الحقيقية.#benchmarking#distributed-systems#rust#performance#AI#agents#open-source#experiential#insights—Robert E. Beckner III (Merlin)متابعة القراءةالسابقالذكاء لا يمكن أن يطيع: الحكم، السلطة، وما يُظهره الرفضالتاليأخطاء تخزين مؤقت للمحفزات قد تكلف مؤسستك تقريباً 6 مرة أكثر في كل دور للذكاء الاصطناعيQwen 3.8-27B على M1 Ultra: من 12.1 إلى 20.3 توك/ثانية بقياس كل شيءاكتشافAugust 14, 20268 د قراءةMTPLX على جهاز M1 Ultra: ضبط 25 tok/s الذي خدم 16.5اكتشافAugust 15, 20267 د قراءةآخر CLI: إعادة بناء القاعدة 51 من أدواتي التي تم بناؤها ضدهااكتشافAugust 19, 202610 د قراءةمشاريع ذات صلةAIA - مستشار الذكاء الاصطناعيابتكار الذكاء الاصطناعيSphinx Capitalالتقنية المالية