Monday 8 January 2018

تصميم أنظمة تداول الكمون المنخفض


تصميم أنظمة تداول الكمون المنخفض
الحصول على فيا أب ستور قراءة هذه المشاركة في التطبيق لدينا!
ما هو مبدأ الكمون المنخفض في تطبيق التداول؟
يبدو أن جميع البنوك الاستثمارية الكبرى تستخدم C ++ في أونيكس (لينكس، سولاريس) لتطبيقات الكمون المنخفض / عالية التردد الخادم. كيف يحقق الناس الكمون المنخفض في تداول الأسهم عالية التردد؟ أي كتاب يعلم كيفية تحقيق ذلك؟
تحقق من هذه المواقع قد تحصل على بعض فكرة عن البرمجة الكمون المنخفض.
ولكن كن على علم بأن بعض الرموز قد لا تكون موحدة. مما يعني أنه لن لفترة أطول.

11 أفضل الممارسات لأنظمة الكمون المنخفض.
منذ 8 سنوات منذ لاحظت جوجل أن 500ms اضافية من الكمون انخفض حركة المرور بنسبة 20٪ وأمازون أدركت أن 100ms من الكمون اضافية انخفضت المبيعات بنسبة 1٪. ومنذ ذلك الحين، كان المطورون يتسابقون إلى أسفل منحنى الكمون، وبلغت ذروتها في مطوري الواجهة الأمامية الذين يضغطون على كل ملي ثانية ثانية من جافا سكريبت و كس وحتى هتمل. ما يلي هو المشي العشوائي من خلال مجموعة متنوعة من أفضل الممارسات أن نأخذ في الاعتبار عند تصميم أنظمة الكمون المنخفض. معظم هذه الاقتراحات تؤخذ إلى أقصى حد منطقي ولكن بالطبع يمكن إجراء المبادلات. (بفضل مستخدم مجهول لطرح هذا السؤال على كورا والحصول علي لوضع أفكاري أسفل في الكتابة).
اختر اللغة الصحيحة.
لا يلزم تطبيق لغات البرمجة النصية. على الرغم من أنها تحافظ على الحصول على أسرع وأسرع، عندما كنت تبحث لحلق تلك بالمللي ثانية القليلة من وقت المعالجة الخاصة بك لا يمكن أن يكون النفقات العامة للغة تفسير. بالإضافة إلى ذلك، سوف تحتاج إلى نموذج ذاكرة قوية لتمكين البرمجة الحرة قفل لذلك يجب أن تبحث في جافا، سكالا، C ++ 11 أو الذهاب.
يبقيه كل شيء في الذاكرة.
سيؤدي الإدخال / الإخراج إلى قتل وقت الاستجابة، لذا تأكد من أن جميع بياناتك في الذاكرة. وهذا يعني عموما إدارة هياكل البيانات الخاصة بك في الذاكرة والحفاظ على سجل مستمر، حتى تتمكن من إعادة بناء الدولة بعد إعادة تشغيل الجهاز أو عملية. بعض الخيارات لسجل ثابت تشمل بيتكاسك، كراتي، ليفيلدب و بدب-جي. بدلا من ذلك، قد تكون قادرا على الابتعاد عن تشغيل قاعدة بيانات محلية ثابتة في الذاكرة مثل ريديس أو مونغودب (مع الذاكرة & غ؛ & غ؛ البيانات). لاحظ أنه يمكنك تفقد بعض البيانات على تحطم بسبب مزامنة الخلفية إلى القرص.
إبقاء البيانات ومعالجة كولوكاتد.
القفزات شبكة أسرع من القرص يسعى ولكن حتى لا تزال سوف تضيف الكثير من النفقات العامة. من الناحية المثالية، يجب أن تكون البيانات الخاصة بك تناسب تماما في الذاكرة على مضيف واحد. مع أوس توفير ما يقرب من 1/4 تيرابايت من ذاكرة الوصول العشوائي في السحابة والخوادم المادية التي تقدم متعددة السل وهذا هو ممكن عموما. إذا كنت بحاجة إلى تشغيل على أكثر من مضيف واحد يجب عليك التأكد من أن البيانات والطلبات الخاصة بك مقسمة بشكل صحيح بحيث تتوفر جميع البيانات اللازمة لخدمة طلب معين محليا.
إبقاء النظام غير مستغلة.
يتطلب الكمون المنخفض دائما وجود موارد لمعالجة الطلب. لا تحاول تشغيلها في حدود ما يمكن أن توفره الأجهزة / البرامج. دائما الكثير من غرفة الرأس لرشقات نارية ثم بعض.
احتفظ بمفاتيح السياق إلى أدنى حد ممكن.
مفاتيح السياق هي علامة على أنك تقوم بعمل أكثر حسابا من لديك موارد ل. سوف تحتاج إلى الحد من عدد من المواضيع إلى عدد من النوى على النظام الخاص بك ولربط كل مؤشر الترابط إلى جوهرها.
الحفاظ على قراءات متتابعة.
جميع أشكال التخزين، ويذبل أن يكون التناوب، ومقرها فلاش، أو الذاكرة أداء أفضل بكثير عند استخدامها بالتتابع. عند إصدار قراءات متتابعة إلى الذاكرة التي تؤدي إلى استخدام الجلب المسبق على مستوى ذاكرة الوصول العشوائي وكذلك على مستوى ذاكرة التخزين المؤقت وحدة المعالجة المركزية. إذا فعلت بشكل صحيح، فإن الجزء التالي من البيانات التي تحتاج إليها يكون دائما في ذاكرة التخزين المؤقت L1 الحق قبل الحاجة إليها. أسهل طريقة للمساعدة في هذه العملية على طول هو استخدام الثقيلة من صفائف من أنواع البيانات البدائية أو الهياكل. وينبغي تجنب المؤشرات التالية إما من خلال استخدام قوائم مرتبطة أو من خلال صفائف من الأشياء بأي ثمن.
دفعة يكتب.
هذا يبدو كونتيرينتبيتيف ولكن يمكنك الحصول على تحسينات كبيرة في الأداء عن طريق الخلط يكتب. ومع ذلك، هناك سوء فهم أن هذا يعني أن النظام يجب أن تنتظر وقتا تعسفيا من الوقت قبل القيام الكتابة. بدلا من ذلك، يجب أن تدور خيط واحد في حلقة ضيقة تفعل I / O. سوف كل دفعة دفعة كل البيانات التي وصلت منذ صدر آخر كتابة. وهذا يجعل نظام سريع جدا والتكيف.
احترم ذاكرة التخزين المؤقت.
مع كل هذه التحسينات في مكان، والوصول إلى الذاكرة بسرعة يصبح عنق الزجاجة. تثبيت المواضيع إلى النوى الخاصة بهم يساعد على تقليل تلوث ذاكرة التخزين المؤقت وحدة المعالجة المركزية وتساعد I / O تسلسلي يساعد أيضا على تحميل ذاكرة التخزين المؤقت. أبعد من ذلك، يجب أن تبقي أحجام الذاكرة أسفل باستخدام أنواع البيانات البدائية حتى المزيد من البيانات يناسب في ذاكرة التخزين المؤقت. بالإضافة إلى ذلك، يمكنك أن تبحث في الخوارزميات مخبأ مخبأ التي تعمل من خلال كسر بشكل متكرر البيانات إلى أن تناسبها في ذاكرة التخزين المؤقت ومن ثم القيام بأي معالجة اللازمة.
عدم حجب قدر الإمكان.
تكوين صداقات مع عدم حجب وانتظار هياكل البيانات الحرة والخوارزميات. في كل مرة كنت تستخدم قفل لديك للذهاب إلى كومة لنظام التشغيل للتوسط القفل الذي هو النفقات العامة الضخمة. في كثير من الأحيان، إذا كنت تعرف ما تقومون به، يمكنك الحصول على جميع أنحاء الأقفال عن طريق فهم نموذج الذاكرة من جفم، C ++ 11 أو الذهاب.
غير المتزامنة قدر الإمكان.
أي معالجة وخاصة أي I / O التي ليست ضرورية تماما لبناء الاستجابة ينبغي أن يتم خارج المسار الحرج.
موازاة قدر الإمكان.
أي معالجة وخاصة أي I / O التي يمكن أن تحدث بالتوازي يجب أن يتم بالتوازي. على سبيل المثال إذا كانت إستراتيجية التوفر العالية تتضمن تسجيل المعاملات إلى القرص وإرسال المعاملات إلى خادم ثانوي يمكن أن تحدث هذه الإجراءات بالتوازي.
تقريبا كل هذا يأتي من متابعة ما لماكس يفعل مع مشروع ديسروبتور بهم. اطلع على ذلك واتبع أي شيء يفعله مارتن طومسون.
شارك هذا:
ذات صلة.
نشرت من قبل.
بنيامين دارفلر.
29 أفكار حول & لدكو؛ 11 أفضل الممارسات لأنظمة الكمون المنخفض & رديقو؛
وسعيدة أن تكون على قائمتك 🙂
مادة جيدة. لحم البقر: لا يوجد نموذج ذاكرة متطور مثل جافا أو C ++ 11. إذا كان النظام الخاص بك يناسب مع الذهاب الروتينية والقنوات المعمارية انها كل شيء جيد آخر لا حظ. عفيك لا يمكنك الانسحاب من جدولة وقت التشغيل لذلك لا توجد المواضيع أوس الأصلي والقدرة على بناء الخاص بك قفل هياكل البيانات المجانية مثل (طوابير سبسك / حلقة مخازن) أيضا تفتقر بشدة.
شكرا على الرد. في حين أن نموذج ذاكرة الذهاب (غولانغ / ريف / ميم) قد لا تكون قوية مثل جافا أو C ++ 11 كنت تحت الانطباع أنه لا يزال بإمكانك إدارة لإنشاء هياكل خالية من قفل البيانات استخدامه. على سبيل المثال جيثب / تكستنود / غرينغو، جيثب / سكرينر / لفريكو و جيثب / موشيرا / غولفهاش. ربما أنا & # 8217؛ م في عداد المفقودين شيئا؟ باعتراف الجميع أنا أعرف أقل بكثير عن الذهاب من جفم.
بنيامين، نموذج ذاكرة الذهاب مفصلة هنا: غولانغ / ريف / ميم هو في الغالب من حيث القنوات والمكسرات. نظرت من خلال الحزم التي قمت بإدراجها وفي حين أن هياكل البيانات هناك & # 8220؛ قفل الحرة & # 8221؛ فهي لا تعادل ما يمكن بناء واحد في جافا / C ++ 11. حزمة التزامن حتى الآن، لا يوجد لديها دعم للذرات استرخاء أو دلالات اكتساب / الافراج عن C ++ 11. وبدون هذا الدعم من الصعب لبناء هياكل البيانات سبسك كما كفاءة تلك الممكنة في C ++ / جافا. المشاريع التي تربط استخدامها atomic. Add & # 8230؛ الذي هو ذري متسقة بالتتابع. إنه & # 8217؛ s بنيت مع زاد كما ينبغي أن يكون & # 8211؛ جيثب / تونير / golang / فقاعة / الماجستير / SRC / PKG / المزامنة / الذري / asm_amd64.s.
أنا لا أحاول ضرب. يستغرق الحد الأدنى من الجهد لكتابة المتزامنة إو والمتزامنة.
رمز سريع بما فيه الكفاية لمعظم الناس. يتم ضبطها للغاية مكتبة ستد للأداء. غولانغ لديها أيضا دعم للهيكلات التي مفقود في جافا. ولكن كما هو عليه، وأعتقد أن نموذج الذاكرة التبسيط ووقت التشغيل روتينية تقف في طريق بناء نوع من الأنظمة التي تتحدث عنها.
أشكركم على الرد في العمق. آمل أن يجد الناس هذا ذهابا وإيابا مفيدة.
في حين أن & أمب؛ 8222؛ مواطن & # 8217؛ اللغة ربما أفضل، انها & # 8217؛ ق ليس مطلوبا بدقة. الفيسبوك أظهر لنا أنه يمكن القيام به في فب. منحهم استخدام فب قبل تجميعها مع آلة هفم بهم. ولكن من الممكن!
للأسف فب لا يزال يفتقر إلى نموذج ذاكرة مقبولة حتى لو هفم تحسن كبير في سرعة التنفيذ.
بينما أنا & # 8217؛ ليرة لبنانية المعركة لاستخدام اللغات على مستوى عال بقدر ما الرجل القادم، وأعتقد أن الطريقة الوحيدة لتحقيق تطبيقات الكمون المنخفض الناس يبحثون عن إسقاط لأسفل إلى لغة مثل C. يبدو أن أكثر صرامة هو أن يكتب بلغة، وأسرع ينفذ.
أود أن أوصي بشدة أن ننظر إلى العمل الذي يجري في المشاريع والمدونات التي ارتبطت. و جفم تتحول بسرعة إلى بقعة ساخنة لهذه الأنواع من الأنظمة لأنها توفر نموذج ذاكرة قوية وجمع القمامة التي تمكن البرمجة الحرة القفل الذي يكاد يكون أو مستحيلا تماما مع نموذج ذاكرة ضعيفة أو غير معروف والعدادات المرجعية لإدارة الذاكرة.
أنا & # 8217؛ ليرة لبنانية نلقي نظرة، بنيامين. شكرا لافتا بها.
جمع القمامة للبرمجة الحرة قفل هو قليلا من الآلات السابقين ديوس. يمكن بناء كل من مبمك وطوابير سبسك دون الحاجة إلى غ. هناك أيضا الكثير من الطرق للقيام قفل البرمجيات الحرة دون جمع القمامة والعد إشارة ليست الطريقة الوحيدة. تقدم مؤشرات المخاطر و رسيو و بروس-كولكتورس الخ الدعم للاستصلاح المؤجل وعادة ما يتم ترميزها لدعم خوارزمية (ليست عامة)، وبالتالي فهي عادة أسهل بكثير للبناء. وبطبيعة الحال فإن المفاضلة تكمن في حقيقة أن غس جودة الإنتاج لديها الكثير من العمل وضعت فيها، وسوف تساعد مبرمج أقل خبرة كتابة خوارزميات خالية من القفل (ينبغي أن تفعل ذلك على الإطلاق؟) دون ترميز حتى نظم الاستصلاح المؤجل . بعض الروابط عن العمل المنجز في هذا المجال: cs. toronto. edu/
نعم C / C ++ حصلت مؤخرا على نموذج الذاكرة، ولكن هذا لا يعني أنها كانت غير مناسبة تماما لرمز خالية من القفل في وقت سابق. دول مجلس التعاون الخليجي وغيرها من مترجمين ذات جودة عالية وكان مترجم توجيهات محددة للقيام قفل البرمجيات الحرة على منصات معتمدة لفترة طويلة حقا & # 8211؛ لم تكن موحدة في اللغة. وقد قدمت لينكس وغيرها من المنصات هذه البدايات لبعض الوقت أيضا. وضع جافا & # 8217؛ s فريدة من نوعها أنها قدمت نموذج ذاكرة رسمية أنه يضمن للعمل على جميع المنصات المعتمدة. على الرغم من أن هذا هو رهيبة من حيث المبدأ، ومعظم المطورين الجانب الخادم تعمل على منصة واحدة (لينكس / ويندوز). كان لديهم بالفعل أدوات لبناء رمز الحرة قفل لمنصاتهم.
غ هو أداة عظيمة ولكن ليست واحدة ضرورية. لديها تكلفة سواء من حيث الأداء والتعقيد (كل الحيل اللازمة لتجنب ستو غ). C ++ 11 / C11 لديها بالفعل دعم لنماذج الذاكرة المناسبة. دعونا لا ننسى أن جفمس ليس لديهم أي مسؤولية لدعم أبي غير آمنة في المستقبل. الرمز غير الآمن هو & # 8220؛ غير آمن & # 8221؛ حتى تفقد فوائد ميزات الأمان جافا & # 8217؛ s. وأخيرا المنظمة البحرية الدولية رمز غير آمنة تستخدم لتخطيط الذاكرة ومحاكاة ستروكتس في جافا يبدو أبشع بكثير من C / C + + ستروكتس حيث المترجم يفعل ذلك العمل بالنسبة لك بطريقة موثوق بها. C و C ++ أيضا توفير الوصول إلى كل مستوى منخفض منصة أدوات الطاقة محددة مثل بوس إنز، سس / أفكس / نيون الخ يمكنك حتى لحن تخطيط التعليمات البرمجية الخاصة بك من خلال البرامج النصية رابط! السلطة التي تقدمها سلسلة C / C ++ أداة لا مثيل لها حقا من قبل جفم. جافا هو منصة كبيرة لا أقل، ولكن أعتقد أنه من أكبر ميزة هي أن منطق الأعمال العادية (90٪ من التعليمات البرمجية؟) لا تزال تعتمد على غ وميزات السلامة والاستفادة من المكتبات ضبطها للغاية واختبارها مكتوبة مع غير آمنة. هذا هو مفاضلة كبيرة بين الحصول على آخر 5٪ من العطور وكونها منتجة. إن المفاضلة المنطقية لكثير من الناس ولكن المفاضلة لا تقل. كتابة تعقيدا رمز التطبيق في C / C ++ هو كابوس بعد كل شيء.
أون مون، 10 مارس، 2017 في 12:52 بيإم، كتب كوديبندنتس:
وGT. غراهام سوان علق: & # 8220؛ أنا & # 8217؛ سوف نلقي نظرة، بنيامين. شكرا ل & غ؛ لافتا لهم. & # 8221؛
مفقود 12: لا تستخدم غاربادج اللغات التي تم جمعها. غ هو عنق الزجاجة في ورسستاس. ومن المرجح أن يوقف جميع المواضيع. إنه عالمي. فإنه يصرف المهندس المعماري لإدارة واحدة من أكثر الموارد كريتال (وحدة المعالجة المركزية بالقرب من الذاكرة) نفسه.
في الواقع الكثير من هذا العمل يأتي مباشرة من جافا. للقيام قفل البرمجيات الحرة الحق تحتاج إلى نموذج ذاكرة واضحة التي c + اكتسبت مؤخرا فقط. إذا كنت تعرف كيفية العمل مع غ وليس ضده يمكنك إنشاء أنظمة الكمون المنخفض في كثير من الأحيان مع سهولة أكثر من ذلك بكثير.
يجب أن أتفق مع بن هنا. لقد أحرز الكثير من التقدم في موازنات جنرال الكتريك في العقد الماضي أو نحو ذلك مع جامع G1 كونه أحدث التشويش. قد يستغرق القليل من الوقت لضبط كومة ومقابض مختلفة للحصول على غ لجمع مع ما يقرب من أي وقفة، ولكن هذا يتضاءل بالمقارنة مع الوقت المطور الذي يستغرقه لعدم وجود غ.
يمكنك حتى أن تذهب خطوة أبعد وإنشاء أنظمة تنتج القمامة القليل جدا التي يمكنك بسهولة دفع غ الخاص بك خارج نافذة التشغيل الخاصة بك. هذه هي الطريقة التي جميع المحلات التجارية عالية التردد تفعل ذلك عند تشغيل على جفم.
جمع القمامة للبرمجة الحرة قفل هو قليلا من الآلات السابقين ديوس. يمكن بناء كل من مبمك وطوابير سبسك دون الحاجة إلى غ. هناك أيضا الكثير من الطرق للقيام قفل البرمجيات الحرة دون جمع القمامة والعد إشارة ليست الطريقة الوحيدة. وتوفر مؤشرات المخاطر، و رسيو، و جامعي الوكالء، إلخ، الدعم لالستصالح المؤجل ويتم ترميزها لدعم خوارزمية) ليست عامة (، وبالتالي فهي أسهل بكثير في البناء. وبطبيعة الحال فإن المفاضلة تكمن في حقيقة أن غس جودة الإنتاج لديها الكثير من العمل وضعت فيها، وسوف تساعد مبرمج أقل خبرة كتابة خوارزميات خالية من القفل (ينبغي أن تفعل ذلك على الإطلاق؟) دون ترميز حتى نظم الاستصلاح المؤجل . بعض الروابط عن العمل المنجز في هذا المجال: cs. toronto. edu/
نعم C / C ++ حصلت مؤخرا على نموذج الذاكرة، ولكن هذا لا يعني أنها كانت غير مناسبة تماما لرمز خالية من القفل في وقت سابق. دول مجلس التعاون الخليجي وغيرها من مترجمين ذات جودة عالية وكان مترجم توجيهات محددة للقيام قفل البرمجيات الحرة على منصات معتمدة لفترة طويلة حقا & # 8211؛ لم تكن موحدة في اللغة. وقد قدمت لينكس وغيرها من المنصات هذه البدايات لبعض الوقت أيضا. وضع جافا & # 8217؛ s فريدة من نوعها أنها قدمت نموذج ذاكرة رسمية أنه يضمن للعمل على جميع المنصات المعتمدة. على الرغم من أن هذا هو رهيبة من حيث المبدأ، ومعظم المطورين الجانب الخادم تعمل على منصة واحدة (لينكس / ويندوز). لديهم بالفعل أدوات لبناء رمز الحرة قفل لمنصاتهم.
غ هو أداة عظيمة ولكن ليست واحدة ضرورية. لديها تكلفة سواء من حيث الأداء والتعقيد (كل الحيل اللازمة لتأخير وتجنب ستو غ). C ++ 11 / C11 لديها بالفعل دعم لنماذج الذاكرة المناسبة. دعونا لا ننسى أن جفمس ليس لديهم أي مسؤولية لدعم أبي غير آمنة في المستقبل. الرمز غير الآمن هو & # 8220؛ غير آمن & # 8221؛ حتى تفقد فوائد ميزات الأمان جافا & # 8217؛ s. وأخيرا المنظمة البحرية الدولية رمز غير آمنة تستخدم لتخطيط الذاكرة ومحاكاة ستروكتس في جافا يبدو أبشع بكثير من C / C + + ستروكتس حيث المترجم يفعل ذلك العمل بالنسبة لك بطريقة موثوق بها. C و C ++ أيضا توفير الوصول إلى جميع منصة منخفضة المستوى أدوات الطاقة محددة مثل بوس إنز، سس / أفكس / نيون الخ يمكنك حتى ضبط تخطيط التعليمات البرمجية الخاصة بك من خلال البرامج النصية رابط! السلطة التي تقدمها سلسلة C / C ++ أداة لا مثيل لها حقا من قبل جفم. جافا هو منصة كبيرة لا أقل، ولكن أعتقد أنه من أكبر ميزة هي أن منطق الأعمال العادية (90٪ من التعليمات البرمجية؟) لا تزال تعتمد على غ وميزات السلامة والاستفادة من المكتبات ضبطها للغاية واختبارها مكتوبة مع غير آمنة. هذا هو مفاضلة كبيرة بين الحصول على آخر 5٪ من العطور وكونها منتجة. إن المفاضلة المنطقية لكثير من الناس ولكن المفاضلة لا تقل. كتابة تعقيدا رمز التطبيق في C / C ++ هو كابوس بعد كل شيء.
وGT. لا تستخدم غاربادج اللغات التي تم جمعها.
أو على الأقل، & # 8220؛ تقليدي & # 8221؛ جمع القمامة اللغات. لأنهم مختلفون & # 8211؛ في حين أن إرلانغ لديه أيضا جامع، فإنه لا يخلق اختناقات لأنه لا يفعل & # 8217؛ ر & # 8220؛ توقف العالم & # 8221؛ كما جافا في حين جمع القمامة & # 8211؛ بدلا من ذلك أنه يوقف الفردية الصغيرة & # 8220؛ الصغرى المواضيع & # 8221؛ على مقياس ميكروثانية، لذلك لا & # 8217؛ s غير ملحوظ على كبير.
إعادة الكتابة إلى & # 8220؛ التقليدية & # 8221؛ جمع القمامة [i] الخوارزميات [/ i]. في لماكس نستخدم أزول زينغ، ومجرد باستخدام جفم مختلفة مع نهج مختلف لجمع القمامة، ونحن & # 8217؛ شهد تحسينات ضخمة في الأداء، لأن كل من غز الرئيسية والثانوية هي أوامر من حجم أرخص.
هناك تكاليف أخرى تعوض ذلك، بطبيعة الحال: يمكنك استخدام الجحيم من الكثير من كومة الذاكرة المؤقتة، و زينغ إيسن & # 8217؛ ر رخيصة.
ريبلوجيد ذيس أون جافا برورغرام أمثلة وعلق:
واحدة من يجب قراءة المقال لمبرمجي جافا، انها & # 8217؛ ق الدرس سوف تتعلم بعد قضاء وقت كبير ضبط وتطوير أنظمة الكمون المنخفض في جافا في 10 دقيقة.
إحياء خيط قديم، ولكن (بشكل مثير للدهشة) هذا لا بد من الإشارة إلى:
1) اللغات ذات المستوى الأعلى (مثل جافا) لا تريد الحصول على وظائف من الأجهزة التي لا تتوفر في اللغات ذات المستوى الأدنى (مثل C)؛ أن نذكر أن هذا ما يسمى & # 8220؛ مستحيل تماما & # 8221؛ في C في حين يمكن القيام به بسهولة في جافا هو القمامة كاملة دون الاعتراف بأن جافا يعمل على الأجهزة الظاهرية حيث جفم لديه لتجميع الوظائف المطلوبة من قبل جافا ولكن لم توفرها الأجهزة المادية. إذا كان جفم (على سبيل المثال مكتوب في C) يمكن توليف وظيفة X، ثم حتى يمكن مبرمج C.
2) & # 8220؛ لوك فري & # 8221؛ إيسن & # 8217؛ ر ما يعتقده الناس، ما عدا تقريبا من قبيل الصدفة في ظروف معينة، مثل واحد x86 الأساسية؛ مولتيكور x86 لا يمكن تشغيل قفل مجانا دون حواجز الذاكرة، والتي لديها تعقيدات وتكلفة مماثلة لقفل العادية. وفقا 1 أعلاه، إذا قفل يعمل مجانا في بيئة معينة، وذلك لأنه مدعوم من قبل الأجهزة، أو محاكاة / توليفها بواسطة البرمجيات في بيئة افتراضية.
نقاط كبيرة جوليوس. النقطة التي كنت أحاولها (ربما غير ناجحة جدا) هي أنه من الصعب للغاية تطبيق العديد من هذه الأنماط في C لأنها تعتمد على غ. انها تتجاوز مجرد استخدام حواجز الذاكرة. عليك أن تنظر في تحرير الذاكرة وكذلك الذي يحصل على صعوبة خاصة عندما كنت تتعامل مع قفل الحرة والانتظار الخوارزميات الحرة. هذا هو المكان الذي يضيف غ فوزا كبيرا. ومع ذلك، أسمع روست بعض الأفكار المثيرة للاهتمام حول ملكية الذاكرة التي قد تبدأ في معالجة بعض هذه القضايا.

تصميم أنظمة تداول الكمون المنخفض
الحصول على فيا أب ستور قراءة هذه المشاركة في التطبيق لدينا!
برمجة الكمون المنخفض.
لقد قرأت الكثير عن الأنظمة المالية الكمون المنخفض (وخاصة منذ حالة التجسس الشهيرة) وفكرة أنظمة الكمون المنخفض في ذهني منذ ذلك الحين. هناك مليون التطبيقات التي يمكن أن تستخدم ما يفعله هؤلاء الرجال، لذلك أود أن أعرف المزيد عن هذا الموضوع. الشيء هو أنني لا يمكن العثور على أي شيء قيمة حول هذا الموضوع. هل يمكن لأي شخص أن يوصي بالكتب والمواقع والأمثلة على أنظمة الكمون المنخفض؟
12 أجوبة.
أنا أعمل لشركة مالية تنتج برامج الكمون المنخفض للتواصل مباشرة مع التبادل (لتقديم الصفقات وأسعار الجري). نحن حاليا تطوير في المقام الأول في جافا. في حين أن الجانب الكمون المنخفض ليس مجالا أعمل في مباشرة لدي فكرة عادلة من المهارات المطلوبة، والتي من شأنها أن تشمل ما يلي في رأيي:
معرفة تفصيلية لنموذج ذاكرة جافا والتقنيات لتجنب جمع القمامة غير الضرورية (مثل تجميع العناصر). ويمكن اعتبار بعض التقنيات المستخدمة عادة "أنماطا مضادة" في بيئة تقليدية و. معرفة مفصلة عن تكب / إب و أودب المتعدد بما في ذلك المرافق لتصحيح الأخطاء وقياس الكمون (على سبيل المثال دتريس على سولاريس). تجربة مع تطبيقات التنميط. المعرفة من حزمة java. nio، تجربة تطوير التطبيقات المستندة إلى نيو المستندة إلى خادم، تجربة تصميم بروتوكولات الأسلاك. لاحظ أيضا أننا عادة ما نتجنب استخدام الأطر والمكتبات الخارجية (مثل غوغل بروتوبوف)، نفضل كتابة الكثير من التعليمات البرمجية المخصصة. معرفة فيكس ومكتبات فيكس التجارية (على سبيل المثال كاميرون فيكس).
للأسف العديد من المهارات لا يمكن إلا أن تكون وضعت "على وظيفة" لأنه لا يوجد بديل عن الخبرة المكتسبة تنفيذ خادم السعر أو محرك التداول على أساس المواصفات. من تبادل أو بائع. ومع ذلك، فمن الجدير بالذكر أيضا أن شركتنا على الأقل تميل إلى عدم البحث عن خبرة محددة في هذه المجالات (أو غيرها) المتخصصة، بدلا من ذلك يفضلون توظيف الناس مع مهارات تحليلية جيدة وحل المشاكل.
الكمون المنخفض هو وظيفة من أشياء كثيرة، وهما أهمها:
وقت الاستجابة للشبكة - أي الوقت المستغرق في الشبكة لإرسال الرسائل أو استقبالها. معالجة الوقت - أي الوقت الذي يستغرقه طلبك للعمل على رسالة / حدث.
لذا، إذا كنت تقول كتابة نظام مطابقة الطلبات، فإن وقت استجابة الشبكة يمثل مدى سرعة تمكنك من تلقي طلب مطابقة الطلب في شبكتك. ويمثل وقت الاستجابة معالجة الوقت الذي يستغرقه طلبك لمطابقة الطلب مع الطلبات المفتوحة والموجودة.
الإرسال المتعدد، أودب، البث المتعدد موثوق بها، تجاوز النواة (بدعم من جافا 7، إنفورماتيكا الترا التراسل، وغيرها الكثير) على شبكات إنفينيباند هي بعض التقنيات الشائعة المستخدمة من قبل جميع الشركات في هذا المجال.
بالإضافة إلى ذلك، هناك أطر برمجة الكمون منخفضة مثل ديسروبتور (code. google/p/disruptor/) التي تنفذ أنماط التصميم للتعامل مع تطبيقات الكمون المنخفض. ما يمكن أن يقتلك هو الحاجة إلى الكتابة إلى دب أو ملفات السجل كجزء من سير العمل الرئيسي الخاص بك. سيكون لديك للتوصل إلى حلول فريدة من نوعها التي تلبي متطلبات المشكلة التي تحاول حلها.
في لغات مثل جافا، تنفيذ التطبيق الخاص بك بحيث أنه يخلق (تقريبا) صفر القمامة يصبح في غاية الأهمية ل الكمون. كما يقول ادامسكي، وجود معرفة نموذج ذاكرة جافا هو في غاية الأهمية. فهم مختلف تطبيقات جفم، وحدودها. أنماط تصميم جافا نموذجية حول خلق كائن صغير هي الأشياء الأولى التي سوف رمي بها من النافذة - لا يمكن للمرء أبدا إصلاح جامع القمامة جافا بما فيه الكفاية لتحقيق الكمون المنخفض - الشيء الوحيد الذي يمكن إصلاحه هو القمامة.
حسنا، ليس فقط "التقليدية" البرمجة في الوقت الحقيقي، كل شيء. أعمل في البورصة - سرعة الملك. مشكلة نموذجية هو ماذا أسرع طريقة للكتابة إلى ملف؟ أسرع طريقة لتسلسل كائن؟ إلخ
أي شيء على البرمجة في الوقت الحقيقي تناسب مشروع القانون. ليس بالضبط ما كنت بعد، وأظن، لكنه مكان جيد للغاية للبدء.
هناك العديد من الإجابة الجيدة في هذا المنصب. وأود أن أضيف تجربتي أيضا.
لتحقيق الكمون المنخفض في جافا لديك للسيطرة على غ في جافا، وهناك العديد من الطرق للقيام بذلك على سبيل المثال قبل تخصيص الأشياء (أي استخدام نمط ذبابة الوزن تصميم)، واستخدام الكائنات البدائية - تروف هو جيد جدا لذلك، جميع البيانات ويستند هيكل على بدائي، إعادة استخدام كائن المثال على سبيل المثال خلق نظام القاموس على نطاق واسع للحد من خلق كائنات جديدة، خيار جيد جدا عند قراءة البيانات من تيار / مأخذ / ديسيبل.
محاولة استخدام ألغو خالية من الانتظار (وهو أمر صعب بعض الشيء)، وقفل ألغو مجانا. يمكنك العثور على طن من الأمثلة على ذلك.
استخدام في الذاكرة الحوسبة. الذاكرة رخيصة، هل يمكن أن يكون بايت تيرا من البيانات في الذاكرة.
إذا كنت تستطيع السيطرة ألغو الحكمة قليلا ثم أنه يعطي أداء جيد جدا.
استخدام التعاطف ميشنيكال - الرجوع لماكس ديسروبتور، إطار ممتاز.
قراءة خلفيات على هذا الموقع، وسوف تحصل على بعض التبصر في ما هو مطلوب للبرمجة الكمون المنخفض.
إذا كنت مهتما في جافا منخفضة الكمون النامية، يجب أن نعرف أنه يمكن القيام به دون رتسج (في الوقت الحقيقي) جفم شريطة أن تبقي جامع القمامة تحت السيطرة. أقترح عليك إلقاء نظرة على هذه المقالة التي تتحدث عن تطوير جافا دون غ النفقات العامة. لدينا أيضا العديد من المقالات الأخرى في موقعنا التي نتحدث عن مكونات جافا الكمون المنخفض.
أود أن أقدم بعض التعليقات حول برمجة الكمون المنخفض. حاليا لدي أكثر من 5 سنوات من الخبرة في تطوير الكمون المنخفض ومحركات التنفيذ عالية في البرمجيات المالية.
هل من الضروري أن نفهم ما هو الكمون؟
يعني وقت الاستجابة أنه يحتاج إلى وقت لإكمال العملية. أنها لا تعتمد بالضرورة على أدوات تطوير كنت تستخدم، مثل جافا، ج ++، وما إلى ذلك، فإنه يعتمد على مهارات البرمجة الخاصة بك، والنظام.
لنفترض أنك تستخدم جافا ولكن خطأ واحد من قبل يمكنك جعل تأخير في العملية. على سبيل المثال قمت بتطوير تطبيق التداول التي على كل سعر تحديث استدعاء بعض الوظائف وهلم جرا. وهذا يمكن أن يؤدي إلى متغيرات إضافية، واستخدام الذاكرة لا لزوم لها، الحلقات غير الضرورية التي قد تسبب تأخير في العملية. نفس التطبيق وضعت في قد تؤدي أفضل من جافا إذا كان المطور يهتم عن الأخطاء المذكورة أعلاه.
كما أنه يعتمد على نظام الخادم الخاص بك، مثل نظام معالج متعددة قد تؤدي بشكل جيد إذا كان التطبيق الخاص بك هو مؤشرات الترابط.
إذا كنت أتذكر بشكل صحيح في الوقت الحقيقي جافا (رتسج) يستخدم في هذا المجال، على الرغم من أنني لا يمكن العثور على مادة جيدة لربط الآن.
وعادة ما يعني العمل في بيئات منخفضة الكمون وجود فهم لتبعات المكالمات وكيفية الحد منها لتقليل سلسلة التبعية. وهذا يشمل استخدام هياكل البيانات والمكتبات لتخزين البيانات القابلة للتخزين المؤقت المطلوبة وكذلك إعادة هيكلة الموارد الموجودة للحد من الترابط.

سبب انخفاض وقت الاستجابة.
استنسخ هذا ويكي محليا.
في نطاق التداول عالية التردد (هفت) يكاد يكون من المستحيل تجنب موضوع انخفاض الكمون. ماذا يعني الكمون المنخفض في هذا السياق؟ الكمون هو مقياس من الوقت للحصول على رد على إجراء معين. لتحقيق انخفاض الكمون استجابة يجب أن تكون سريعة، حيث يتم قياس سريع في كثير من الأحيان في الدقيقة أو نانو ثانية ل هفت. يجب أن تستجيب أنظمة هفت في الوقت المناسب لأحداث السوق وإلا فقدت فرصة التداول في أحسن الأحوال، أو في أسوأ الأحوال يمكن أن يعني خوارزمية التداول تتعرض لمخاطر كبيرة لأنها تأخر السوق.
ما الاسم المنخفض الكمون لا ينقل هو أهمية وجود الكمون متسقة. غالبا ما يكون من المهم أن تكون متسقة أكثر من كونها سريعة معظم الوقت ولكن بطيئة في بعض الأحيان. لذلك أنظمة التداول والتبادلات تسعى إلى عدم مجرد تقديم الكمون المنخفض أنها أيضا محاولة لتقليل التباين. يمكن أن يكون تحقيق الكمون المنخفض مع الحد الأدنى من التباين تحديا حقيقيا عند التعامل مع أوقات الاستجابة تقاس بالميكروثانية، وخاصة في معدلات الحدث التي يمكن أن تكون في الملايين عديدة في الثانية لأكبر الأعلاف.
ولكي يكون النظام مستجيبا جدا عندما يواجه معدلات كبيرة من الأحداث، فإنه يجب أن يكون فعالا بشكل لا يصدق. ليس هناك مجال للنفايات في مثل هذا النظام. يجب أن تدفع كل تعليمات تنفيذها بطريقتها الخاصة وأن تركز فقط على هدف معالجة الأحداث الواردة والاستجابة وفقا لذلك. ويحتاج تصميم هذه الأنظمة إلى نهج مماثل في تصميم الطائرات أو المركبات الفضائية. تم تصميم المركبة الفضائية لتكون الحد الأدنى قدر الإمكان مع المستوى المناسب من ميزات السلامة. وهذا يتطلب فهم دقيق لما هو مطلوب بالضبط والتركيز الحلاقة حاد على الكفاءة. وينبغي عدم حمل أي أمتعة إضافية على الطريق.
لتقليل التباين يتطلب كومة كاملة، أو منصة، فهم بحيث النظام هو دائما إطفاء تكلفة العمليات باهظة الثمن وجميع الخوارزميات لديها تدوين O - O من O (سجل ن) أو حتى أفضل.
يمكن إدخال التباين في جميع الطبقات أو المكدس. على مستوى منخفض جدا يمكن أن يكون المقاطعات سمي التحقق من حالة الأجهزة أو نظام المقاطعات استباق التنفيذ. وعلاوة على ذلك حتى المكدس يمكن أن يكون نظام التشغيل أو الأجهزة الظاهرية إدارة الذاكرة التي يجري تشورنيد من قبل التطبيقات. التباين غالبا ما يأتي من الخوارزميات المستخدمة داخل أنظمة التداول نفسها التي تعبر هياكل البيانات التي يمكن أن تسبب مخبأ-ميسس و O (n) معالجة أو البحث.
ويهدف نهج التصميم الذي يتم اتخاذه إلى برنامج ترميز سب إلى تحقيق أكبر قدر ممكن من الكفاءة والحفاظ على التباين إلى أدنى حد ممكن مع اتباع نهج مناسب للمخاطر في مجال السلامة.
&نسخ؛ 2017 جيثب، Inc. شروط الخصوصية تعليمات حالة الأمان.
لا يمكنك تنفيذ هذا الإجراء في الوقت الحالي.
لقد سجلت الدخول باستخدام علامة تبويب أو نافذة أخرى. أعد التحميل لتحديث الجلسة. لقد سجلت الخروج في علامة تبويب أو نافذة أخرى. أعد التحميل لتحديث الجلسة.

التطور والممارسة: منخفض الكمون التطبيقات الموزعة في المالية.
وصناعة التمويل لديها مطالب فريدة من نوعها لنظم توزيع الكمون المنخفض.
أندرو بروك.
ولكل الأنظمة تقريبا بعض متطلبات الكمون، وتعرف هنا على أنها الوقت اللازم لكي يستجيب النظام للإدخال. (توجد عمليات حسابية غير متوقفة، ولكن لديها عدد قليل من التطبيقات العملية.) تظهر متطلبات الكمون في مجالات المشاكل المتنوعة مثل ضوابط الطيران للطائرات (copter. ardupilot)، والاتصالات الصوتية (queue. acm / detail. cfm؟ إد = 1028895)، متعددة اللاعبين (queue. acm / detail. cfm؟ إد = 971591)، والإعلان عبر الإنترنت (أكويتيادس / في الوقت الحقيقي العطاءات /)، والتجارب العلمية (home. web. cern. ch/about/accelerators/cern-neutrinos-gran - sasso).
الأنظمة الموزعة & مداش؛ حيث يحدث الحساب على أجهزة كمبيوتر متعددة متصلة بالشبكة تتواصل وتنسيق إجراءاتها عن طريق تمرير الرسائل & مداش؛ اعتبارات وقت الاستجابة الخاصة الحالية. وفي السنوات الأخيرة، أدت أتمتة التداول المالي إلى دفع متطلبات الأنظمة الموزعة بمتطلبات زمن الاستجابة الصعبة (التي تقاس في الغالب بالميكروثانية أو حتى النانوثانية؛ انظر الجدول 1) والتوزيع الجغرافي العالمي. يوفر التداول الآلي نافذة على التحديات الهندسية من متطلبات الكمون المتقلص من أي وقت مضى، والتي قد تكون مفيدة لمهندسي البرمجيات في مجالات أخرى.
تركز هذه المقالة على التطبيقات التي يكون فيها زمن الاستجابة (بدلا من الإنتاجية أو الكفاءة أو بعض المقاييس الأخرى) أحد اعتبارات التصميم الأساسية. فراسد بشكل مختلف، "أنظمة الكمون المنخفض" هي تلك التي الكمون هو المقياس الرئيسي للنجاح وعادة ما يكون أصعب القيد على تصميم حولها. تقدم المقالة أمثلة على أنظمة الكمون المنخفض التي توضح العوامل الخارجية التي تدفع الكمون ومن ثم مناقشة بعض النهج الهندسية العملية لنظم البناء التي تعمل في الكمون المنخفض.
لماذا الجميع في مثل هذا امرنا؟
لفهم تأثير الكمون على أحد التطبيقات، من المهم أولا أن نفهم العوامل الخارجية، في العالم الحقيقي التي تدفع المتطلبات. وتوضح الأمثلة التالية من صناعة التمويل أثر بعض العوامل في العالم الحقيقي.
طلب إقتباس التداول.
وفي عام 2003، عملت في مصرف كبير نشر للتو نظاما تجاريا مؤسسيا جديدا للعملة الأجنبية. وكان الاقتباس ومحرك التجارة، وهو J2EE (جافا 2 منصة، الطبعة المؤسسة) تطبيق قيد التشغيل في خادم ويبلوجيك على رأس قاعدة بيانات أوراكل أوقات الاستجابة التي كانت موثوق بها تحت ثانيتين و [مدش]؛ سريع بما فيه الكفاية لضمان تجربة جيدة للمستخدم.
وفي نفس الوقت الذي بدأ فيه موقع البنك على شبكة الإنترنت، تم إطلاق منصة تداول عبر الإنترنت متعددة البنوك. على هذا النظام الأساسي الجديد، سيقوم العميل بتقديم طلب عرض أسعار (رفق) الذي سيتم إرساله إلى عدة بنوك مشاركة. كل بنك سوف يستجيب مع الاقتباس، وسوف العميل اختيار أي واحد لقبوله.
بدأ البنك الذي أعمل فيه مشروعا للاتصال بالمنصة الجديدة متعددة القنوات. وكان المنطق هو أنه بما أن زمن الاستجابة لمدة ثانيتين كان جيدا بما فيه الكفاية لمستخدم على موقع الويب، فإنه ينبغي أن يكون جيدا بما فيه الكفاية للمنصة الجديدة، وبالتالي فإن نفس الاقتباس ومحرك التجارة يمكن إعادة استخدامها. في غضون أسابيع من بدء العمل، ومع ذلك، كان البنك الفوز بنسبة صغيرة من المستغرب من رفقس. كان السبب الجذري هو الكمون. When two banks responded with the same price (which happened quite often), the first response was displayed at the top of the list. Most clients waited to see a few different quotes and then clicked on the one at the top of the list. The result was that the fastest bank often won the client's business—and my bank wasn't the fastest.
The slowest part of the quote-generation process occurred in the database queries loading customer pricing parameters. Adding a cache to the quote engine and optimizing a few other "hot spots" in the code brought quote latency down to the range of roughly 100 milliseconds. With a faster engine, the bank was able to capture significant market share on the competitive quotation platform—but the market continued to evolve.
الجري ونقلت.
By 2006 a new style of currency trading was becoming popular. Instead of a customer sending a specific request and the bank responding with a quote, customers wanted the banks to send a continuous stream of quotes. This streaming-quotes style of trading was especially popular with certain hedge funds that were developing automated trading strategies—applications that would receive streams of quotes from multiple banks and automatically decide when to trade. In many cases, humans were now out of the loop on both sides of the trade.
To understand this new competitive dynamic, it's important to know how banks compute the rates they charge their clients for foreign-exchange transactions. The largest banks trade currencies with each other in the so-called interbank market. The exchange rates set in that market are the most competitive and form the basis for the rates (plus some markup) that are offered to clients. Every time the interbank rate changes, each bank recomputes and republishes the corresponding client rate quotes. If a client accepts a quote (i. e., requests to trade against a quoted exchange rate), the bank can immediately execute an offsetting trade with the interbank market, minimizing risk and locking in a small profit. There are, however, risks to banks that are slow to update their quotes. A simple example can illustrate:
Imagine that the interbank spot market for EUR/USD has rates of 1.3558 / 1.3560. (The term spot means that the agreed-upon currencies are to be exchanged within two business days. Currencies can be traded for delivery at any mutually agreed-upon date in the future, but the spot market is the most active in terms of number of trades.) Two rates are quoted: one for buying (the bid rate), and one for selling (the offered or ask rate). In this case, a participant in the interbank market could sell one euro and receive 1.3558 US dollars in return. Conversely, one could buy one euro for a price of 1.3560 US dollars.
Say that two banks, A and B, are participants in the interbank market and are publishing quotes to the same hedge fund client, C. Both banks add a margin of 0.0001 to the exchange rates they quote to their clients—so both publish quotes of 1.3557 / 1.3561 to client C. Bank A, however, is faster at updating its quotes than bank B, taking about 50 milliseconds while bank B takes about 250 milliseconds. There are approximately 50 milliseconds of network latency between banks A and B and their mutual client C. Both banks A and B take about 10 milliseconds to acknowledge an order, while the hedge fund C takes about 10 milliseconds to evaluate new quotes and submit orders. Table 2 breaks down the sequence of events.
The net effect of this new streaming-quote style of trading was that any bank that was significantly slower than its rivals was likely to suffer losses when market prices changed and its quotes weren't updated quickly enough. At the same time, those banks that could update their quotes fastest made significant profits. Latency was no longer just a factor in operational efficiency or market share—it directly impacted the profit and loss of the trading desk. As the volume and speed of trading increased throughout the mid-2000s, these profits and losses grew to be quite large. (How low can you go? Table 3 shows some examples of approximate latencies of systems and applications across nine orders of magnitude.)
To improve its latency, my bank split its quote and trading engine into distinct applications and rewrote the quote engine in C++. The small delays added by each hop in the network from the interbank market to the bank and onward to its clients were now significant, so the bank upgraded firewalls and procured dedicated telecom circuits. Network upgrades combined with the faster quote engine brought end-to-end quote latency down below 10 milliseconds for clients who were physically located close to our facilities in New York, London, or Hong Kong. Trading performance and profits rose accordingly—but, of course, the market kept evolving.
Engineering systems for low latency.
The latency requirements of a given application can be addressed in many ways, and each problem requires a different solution. There are some common themes, though. First, it is usually necessary to measure latency before it can be improved. Second, optimization often requires looking below abstraction layers and adapting to the reality of the physical infrastructure. Finally, it is sometimes possible to restructure the algorithms (or even the problem definition itself) to achieve low latency.
Lies, damn lies, and statistics.
The first step to solving most optimization problems (not just those that involve software) is to measure the current system's performance. Start from the highest level and measure the end-to-end latency. Then measure the latency of each component or processing stage. If any stage is taking an unusually large portion of the latency, then break it down further and measure the latency of its substages. The goal is to find the parts of the system that contribute the most to the total latency and focus optimization efforts there. This is not always straightforward in practice, however.
For example, imagine an application that responds to customer quote requests received over a network. The client sends 100 quote requests in quick succession (the next request is sent as soon as the prior response is received) and reports total elapsed time of 360 milliseconds—or 3.6 milliseconds on average to service a request. The internals of the application are broken down and measured using the same 100-quote test set:
والثور؛ Read input message from network and parse - 5 microseconds.
والثور؛ Look up client profile - 3.2 milliseconds (3,200 microseconds)
والثور؛ Compute client quote - 15 microseconds.
والثور؛ Log quote - 20 microseconds.
والثور؛ Serialize quote to a response message - 5 microseconds.
والثور؛ Write to network - 5 microseconds.
As clearly shown in this example, significantly reducing latency means addressing the time it takes to look up the client's profile. A quick inspection shows that the client profile is loaded from a database and cached locally. Further testing shows that when the profile is in the local cache (a simple hash table), response time is usually under a microsecond, but when the cache is missed it takes several hundred milliseconds to load the profile. The average of 3.2 milliseconds was almost entirely the result of one very slow response (of about 320 milliseconds) caused by a cache miss. Likewise, the client's reported 3.6-millisecond average response time turns out to be a single very slow response (350 milliseconds) and 99 fast responses that took around 100 microseconds each.
Means and outliers.
Most systems exhibit some variance in latency from one event to the next. In some cases the variance (and especially the highest-latency outliers) drives the design, much more so than the average case. It is important to understand which statistical measure of latency is appropriate to the specific problem. For example, if you are building a trading system that earns small profits when the latency is below some threshold but incurs massive losses when latency exceeds that threshold, then you should be measuring the peak latency (or, alternatively, the percentage of requests that exceed the threshold) rather than the mean. On the other hand, if the value of the system is more or less inversely proportional to the latency, then measuring (and optimizing) the average latency makes more sense even if it means there are some large outliers.
What are you measuring?
Astute readers may have noticed that the latency measured inside the quote server application doesn't quite add up to the latency reported by the client application. That is most likely because they aren't actually measuring the same thing. Consider the following simplified pseudocode:
(In the client application)
for (int i = 0; i < 100; i++)
RequestMessage requestMessage = new RequestMessage(quoteRequest);
long sentTime = getSystemTime();
ResponseMessage responseMessage = receiveMessage();
long quoteLatency = getSystemTime() - sentTime;
(In the quote server application)
RequestMessage requestMessage = receive();
long receivedTime = getSystemTime();
QuoteRequest quoteRequest = parseRequest(requestMessage);
long parseTime = getSystemTime();
long parseLatency = parseTime - receivedTime;
ClientProfile profile = lookupClientProfile(quoteRequest. client);
long profileTime = getSystemTime();
long profileLatency = profileTime - parseTime;
Quote quote = computeQuote(profile);
long computeTime = getSystemTime();
long computeLatency = computeTime - profileTime;
long logTime = getSystemTime();
long logLatency = logTime - computeTime;
QuoteMessage quoteMessage = new QuoteMessage(quote);
long serializeTime = getSystemTime();
long serializationLatency = serializeTime - logTime;
long sentTime = getSystemTime();
long sendLatency = sentTime - serializeTime;
logStats(parseLatency, profileLatency, computeLatency,
logLatency, serializationLatency, sendLatency);
Note that the elapsed time measured by the client application includes the time to transmit the request over the network, as well as the time for the response to be transmitted back. The quote server, on the other hand, measures the time elapsed only from the arrival of the quote to when it is sent (or more precisely, when the send method returns). The 350-microsecond discrepancy between the average response time measured by the client and the equivalent measurement by the quote server could be caused by the network, but it might also be the result of delays within the client or server. Moreover, depending on the programming language and operating system, checking the system clock and logging the latency statistics may introduce material delays.
This approach is simplistic, but when combined with code-profiling tools to find the most commonly executed code and resource contention, it is usually good enough to identify the first (and often easiest) targets for latency optimization. It's important to keep this limitation in mind, though.
Measuring distributed systems latency via network traffic capture.
Distributed systems pose some additional challenges to latency measurement—as well as some opportunities. In cases where the system is distributed across multiple servers it can be hard to correlate timestamps of related events. The network itself can be a significant contributor to the latency of the system. Messaging middleware and the networking stacks of operating systems can be complex sources of latency.
At the same time, the decomposition of the overall system into separate processes running on independent servers can make it easier to measure certain interactions accurately between components of the system over the network. Many network devices (such as switches and routers) provide mechanisms for making timestamped copies of the data that traverse the device with minimal impact on the performance of the device. Most operating systems provide similar capabilities in software, albeit with a somewhat higher risk of delaying the actual traffic. Timestamped network-traffic captures (often called packet captures ) can be a useful tool to measure more precisely when a message was exchanged between two parts of the system. These measurements can be obtained without modifying the application itself and generally with very little impact on the performance of the system as a whole. (See wireshark and tcpdump.)
One of the challenges of measuring performance at short time scales across distributed systems is clock synchronization. In general, to measure the time elapsed from when an application on server A transmits a message to when the message reaches a second application on server B, it is necessary to check the time on A's clock when the message is sent and on B's clock when the message arrives, and then subtract those two timestamps to determine the latency. If the clocks on A and B are not in sync, then the computed latency will actually be the real latency plus the clock skew between A and B.
When is this a problem in the real world? Real-world drift rates for the quartz oscillators that are used in most commodity server motherboards are on the order of 10^-5, which means that the oscillator may be expected to drift by 10 microseconds each second. If uncorrected, it may gain or lose as much as a second over the course of a day. For systems operating at time scales of milliseconds or less, clock skew may render the measured latency meaningless. Oscillators with significantly lower drift rates are available, but without some form of synchronization, they will eventually drift apart. Some mechanism is needed to bring each server's local clock into alignment with some common reference time.
Developers of distributed systems should understand NTP (Network Time Protocol) at a minimum and are encouraged to learn about PTP (Precision Time Protocol) and usage of external signals such as GPS to obtain high-accuracy time synchronization in practice. Those who need time accuracy at the sub-microsecond scale will want to become familiar with hardware implementations of PTP (especially at the network interface) as well as tools for extracting time information from each core's local clock. (See tools. ietf/html/rfc1305, tools. ietf/html/rfc5905, nist. gov/el/isd/ieee/ieee1588.cfm, and queue. acm/detail. cfm? id=2354406.)
Abstraction versus Reality.
Modern software engineering is built upon abstractions that allow programmers to manage the complexity of ever-larger systems. Abstractions do this by simplifying or generalizing some aspect of the underlying system. This doesn't come for free, though—simplification is an inherently lossy process and some of the lost details may be important. Moreover, abstractions are often defined in terms of function rather than performance.
Somewhere deep below an application are electrical currents flowing through semiconductors and pulses of light traveling down fibers. Programmers rarely need to think of their systems in these terms, but if their conceptualized view drifts too far from reality they are likely to experience unpleasant surprises.
Four examples illustrate this point:
والثور؛ TCP provides a useful abstraction over UDP (User Datagram Protocol) in terms of delivery of a sequence of bytes. TCP ensures that bytes will be delivered in the order they were sent even if some of the underlying UDP datagrams are lost. The transmission latency of each byte (the time from when it is written to a TCP socket in the sending application until it is read from the corresponding receiving application's socket) is not guaranteed, however. In certain cases (specifically when an intervening datagram is lost) the data contained in a given UDP datagram may be delayed significantly from delivery to the application, while the missed data ahead of it is recovered.
والثور؛ Cloud hosting provides virtual servers that can be created on demand without precise control over the location of the hardware. An application or administrator can create a new virtual server "on the cloud" in less than a minute—an impossible feat when assembling and installing physical hardware in a data center. Unlike the physical server, however, the location of the cloud server or its location in the network topology may not be precisely known. If a distributed application depends on the rapid exchange of messages between servers, the physical proximity of those servers may have a significant impact on the overall application performance.
والثور؛ Threads allow developers to decompose a problem into separate sequences of instructions that can be allowed to run concurrently, subject to certain ordering constraints, and that can operate on shared resources (such as memory). This allows developers to take advantage of multicore processors without needing to deal directly with issues of scheduling and core assignment. In some cases, however, the overhead of context switches and passing data between cores can outweigh the advantages gained by concurrency.
والثور؛ Hierarchical storage and cache-coherency protocols allow programmers to write applications that use large amounts of virtual memory (on the order of terabytes in modern commodity servers), while experiencing latencies measured in nanoseconds when requests can be serviced by the closest caches. The abstraction hides the fact that the fastest memory is very limited in capacity (e. g., register files on the order of a few kilobytes), while memory that has been swapped out to disk may incur latencies in the tens of milliseconds.
Each of these abstractions is extremely useful but can have unanticipated consequences for low-latency applications. There are some practical steps to take to identify and mitigate latency issues resulting from these abstractions.
Messaging and Network Protocols.
The near ubiquity of IP-based networks means that regardless of which messaging product is in use, under the covers the data is being transmitted over the network as a series of discrete packets. The performance characteristics of the network and the needs of an application can vary dramatically—so one size almost certainly does not fit all when it comes to messaging middleware for latency-sensitive distributed systems.
There's no substitute for getting under the hood here. For example, if an application runs on a private network (you control the hardware), communications follow a publisher/subscriber model, and the application can tolerate a certain rate of data loss, then raw multicast may offer significant performance gains over any middleware based on TCP. If an application is distributed across very long distances and data order is not important, then a UDP-based protocol may offer advantages in terms of not stalling to resend a missed packet. If TCP-based messaging is being used, then it's worth keeping in mind that many of its parameters (especially buffer sizes, slow start, and Nagle's algorithm) are configurable and the "out-of-the-box" settings are usually optimized for throughput rather than latency (queue. acm/detail. cfm? id=2539132).
The physical constraint that information cannot propagate faster than the speed of light is a very real consideration when dealing with short time scales and/or long distances. The two largest stock exchanges, NASDAQ and NYSE, run their matching engines in data centers in Carteret and Mahwah, New Jersey, respectively. A ray of light takes 185 microseconds to travel the 55.4-km distance between these two locations. Light in a glass fiber with a refractive index of 1.6 and following a slightly longer path (roughly 65 km) takes almost 350 microseconds to make the same one-way trip. Given that the computations involved in trading decisions can now be made on time scales of 10 microseconds or less, signal propagation latency cannot be ignored.
Decomposing a problem into a number of threads that can be executed concurrently can greatly increase performance, especially in multicore systems, but in some cases it may actually be slower than a single-threaded solution.
Specifically, multithreaded code incurs overhead in the following three ways:
والثور؛ When multiple threads operate on the same data, controls are required to ensure that the data remains consistent. This may include acquisition of locks or implementations of read or write barriers. In multicore systems, these concurrency controls require that thread execution is suspended while messages are passed between cores. If a lock is already held by one thread, then other threads seeking that lock will need to wait until the first one is finished. If several threads are frequently accessing the same data, there may be significant contention for locks.
والثور؛ Similarly, when multiple threads operate on the same data, the data itself must be passed between cores. If several threads access the same data but each performs only a few computations on it, the time required to move the data between cores may exceed the time spent operating on it.
والثور؛ Finally, if there are more threads than cores, the operating system must periodically perform a context switch in which the thread running on a given core is halted, its state is saved, and another thread is allowed to run. The cost of a context switch can be significant. If the number of threads far exceeds the number of cores, context switching can be a significant source of delay.
In general, application design should use threads in a way that represents the inherent concurrency of the underlying problem. If the problem contains significant computation that can be performed in isolation, then a larger number of threads is called for. On the other hand, if there is a high degree of interdependency between computations or (worst case) if the problem is inherently serial, then a single-threaded solution may make more sense. In both cases, profiling tools should be used to identify excessive lock contention or context switching. Lock-free data structures (now available for several programming languages) are another alternative to consider (queue. acm/detail. cfm? id=2492433).
It's also worth noting that the physical arrangement of cores, memory, and I/O may not be uniform. For example, on modern Intel microprocessors certain cores can interact with external I/O (e. g., network interfaces) with much lower latency than others, and exchanging data between certain cores is faster than others. As a result, it may be advantageous explicitly to pin specific threads to specific cores (queue. acm/detail. cfm? id=2513149).
Hierarchical storage and cache misses.
All modern computing systems use hierarchical data storage—a small amount of fast memory combined with multiple levels of larger (but slower) memory. Recently accessed data is cached so that subsequent access is faster. Since most applications exhibit a tendency to access the same memory multiple times in a short period, this can greatly increase performance. To obtain maximum benefit, however, the following three factors should be incorporated into application design:
والثور؛ Using less memory overall (or at least in the parts of the application that are latency-sensitive) increases the probability that needed data will be available in one of the caches. In particular, for especially latency-sensitive applications, designing the app so that frequently accessed data fits within the CPU's caches can significantly improve performance. Specifications vary but Intel's Haswell microprocessors, for example, provide 32 KB per core for L1 data cache and up to 40 MB of shared L3 cache for the entire CPU.
والثور؛ Repeated allocation and release of memory should be avoided if reuse is possible. An object or data structure that is allocated once and reused has a much greater chance of being present in a cache than one that is repeatedly allocated anew. This is especially true when developing in environments where memory is managed automatically, as overhead caused by garbage collection of memory that is released can be significant.
والثور؛ The layout of data structures in memory can have a significant impact on performance because of the architecture of caches in modern processors. While the details vary by platform and are outside the scope of this article, it is generally a good idea to prefer arrays as data structures over linked lists and trees and to prefer algorithms that access memory sequentially since these allow the hardware prefetcher (which attempts to load data preemptively from main memory into cache before it is requested by the application) to operate most efficiently. Note also that data that will be operated on concurrently by different cores should be structured so that it is unlikely to fall in the same cache line (the latest Intel CPUs use 64-byte cache lines) to avoid cache-coherency contention.
A note on premature optimization.
The optimizations just presented should be considered part of a broader design process that takes into account other important objectives including functional correctness, maintainability, etc. Keep in mind Knuth's quote about premature optimization being the root of all evil; even in the most performance-sensitive environments, it is rare that a programmer should be concerned with determining the correct number of threads or the optimal data structure until empirical measurements indicate that a specific part of the application is a hot spot. The focus instead should be on ensuring that performance requirements are understood early in the design process and that the system architecture is sufficiently decomposable to allow detailed measurement of latency when and as optimization becomes necessary. Moreover (and as discussed in the next section), the most useful optimizations may not be in the application code at all.
Changes in Design.
The optimizations presented so far have been limited to improving the performance of a system for a given set of functional requirements. There may also be opportunities to change the broader design of the system or even to change the functional requirements of the system in a way that still meets the overall objectives but significantly improves performance. Latency optimization is no exception. In particular, there are often opportunities to trade reduced efficiency for improved latency.
Three real-world examples of design tradeoffs between efficiency and latency are presented here, followed by an example where the requirements themselves present the best opportunity for redesign.
In certain cases trading efficiency for latency may be possible, especially in systems that operate well below their peak capacity. In particular, it may be advantageous to compute possible outputs in advance, especially when the system is idle most of the time but must react quickly when an input arrives.
A real-world example can be found in the systems used by some firms to trade stocks based on news such as earnings announcements. Imagine that the market expects Apple to earn between $9.45 and $12.51 per share. The goal of the trading system, upon receiving Apple's actual earnings, would be to sell some number of shares Apple stock if the earnings were below $9.45, buy some number of shares if the earnings were above $12.51, and do nothing if the earnings fall within the expected range. The act of buying or selling stocks begins with submitting an order to the exchange. The order consists of (among other things) an indicator of whether the client wishes to buy or sell, the identifier of the stock to buy or sell, the number of shares desired, and the price at which the client wishes to buy or sell. Throughout the afternoon leading up to Apple's announcement, the client would receive a steady stream of market-data messages that indicate the current price at which Apple's stock is trading.
A conventional implementation of this trading system would cache the market-price data and, upon receipt of the earnings data, decide whether to buy or sell (or neither), construct an order, and serialize that order to an array of bytes to be placed into the payload of a message and sent to the exchange.
An alternative implementation performs most of the same steps but does so on every market-data update rather than only upon receipt of the earnings data. Specifically, when each market-data update message is received, the application constructs two new orders (one to buy, one to sell) at the current prices and serializes each order into a message. The messages are cached but not sent. When the next market-data update arrives, the old order messages are discarded and new ones are created. When the earnings data arrives, the application simply decides which (if either) of the order messages to send.
The first implementation is clearly more efficient (it has a lot less wasted computation), but at the moment when latency matters most (i. e., when the earnings data has been received), the second algorithm is able to send out the appropriate order message sooner. Note that this example presents application-level precomputation; there is an analogous process of branch prediction that takes place in pipelined processors which can also be optimized (via guided profiling) but is outside the scope of this article.
Keeping the system warm.
In some low-latency systems long delays may occur between inputs. During these idle periods, the system may grow "cold." Critical instructions and data may be evicted from caches (costing hundreds of nanoseconds to reload), threads that would process the latency-sensitive input are context-switched out (costing tens of microseconds to resume), CPUs may switch into power-saving states (costing a few milliseconds to exit), etc. Each of these steps makes sense from an efficiency standpoint (why run a CPU at full power when nothing is happening?), but all of them impose latency penalties when the input data arrives.
In cases where the system may go for hours or days between input events there is a potential operational issue as well: configuration or environmental changes may have "broken" the system in some important way that won't be discovered until the event occurs—when it's too late to fix.
A common solution to both problems is to generate a continuous stream of dummy input data to keep the system "warm." The dummy data needs to be as realistic as possible to ensure that it keeps the right data in the caches and that breaking changes to the environment are detected. The dummy data needs to be reliably distinguishable from legitimate data, though, to prevent downstream systems or clients from being confused.
It is common in many systems to process the same data through multiple independent instances of the system in parallel, primarily for the improved resiliency that is conferred. If some component fails, the user will still receive the result needed. Low-latency systems gain the same resiliency benefits of parallel, redundant processing but can also use this approach to reduce certain kinds of variable latency.
All real-world computational processes of nontrivial complexity have some variance in latency even when the input data is the same. These variations can be caused by minute differences in thread scheduling, explicitly randomized behaviors such as Ethernet's exponential back-off algorithm, or other unpredictable factors. Some of these variations can be quite large: page faults, garbage collections, network congestion, etc., can all cause occasional delays that are several orders of magnitude larger than the typical processing latency for the same input.
Running multiple, independent instances of the system, combined with a protocol that allows the end recipient to accept the first result produced and discard subsequent redundant copies, both provides the benefit of less-frequent outages and avoids some of the larger delays.
Stream processing and short circuits.
Consider a news analytics system whose requirements are understood to be "build an application that can extract corporate earnings data from a press release document as quickly as possible." Separately, it was specified that the press releases would be pushed to the system via FTP. The system was thus designed as two applications: one that received the document via FTP, and a second that parsed the document and extracted the earnings data. In the first version of this system, an open-source FTP server was used as the first application, and the second application (the parser) assumed that it would receive a fully formed document as input, so it did not start parsing the document until it had fully arrived.
Measuring the performance of the system showed that while parsing was typically completed in just a few milliseconds, receiving the document via FTP could take tens of milliseconds from the arrival of the first packet to the arrival of the last packet. Moreover, the earnings data was often present in the first paragraph of the document.
In a multistep process it may be possible for subsequent stages to start processing before prior stages have finished, sometimes referred to as stream-oriented or pipelined processing . This can be especially useful if the output can be computed from a partial input. Taking this into account, the developers reconceived their overall objective as "build a system that can deliver earnings data to the client as quickly as possible." This broader objective, combined with the understanding that the press release would arrive via FTP and that it was possible to extract the earnings data from the first part of the document (i. e., before the rest of the document had arrived), led to a redesign of the system.
The FTP server was rewritten to forward portions of the document to the parser as they arrived rather than wait for the entire document. Likewise, the parser was rewritten to operate on a stream of incoming data rather than on a single document. The result was that in many cases the earnings data could be extracted within just a few milliseconds of the start of the arrival of the document. This reduced overall latency (as observed by the client) by several tens of milliseconds without the internal implementation of the parsing algorithm being any faster.
استنتاج.
While latency requirements are common to a wide array of software applications, the financial trading industry and the segment of the news media that supplies it with data have an especially competitive ecosystem that produces challenging demands for low-latency distributed systems.
As with most engineering problems, building effective low-latency distributed systems starts with having a clear understanding of the problem. The next step is measuring actual performance and then, where necessary, making improvements. In this domain, improvements often require some combination of digging below the surface of common software abstractions and trading some degree of efficiency for improved latency.
LOVE IT, HATE IT? LET US KNOW.
Andrew Brook is the CTO of Selerity, a provider of realtime news, data, and content analytics. Previously he led development of electronic currency trading systems at two large investment banks and launched a pre-dot-com startup to deliver AI-powered scheduling software to agile manufacturers. His expertise lies in applying distributed, realtime systems technology and data science to real-world business problems. He finds Wireshark to be more interesting than PowerPoint.
&نسخ؛ 2018 ACM 1542-7730/14/0300 $10.00.
An apostate's opinion.
Ivan Beschastnikh, Patty Wang, Yuriy Brun, Michael D, Ernst - Debugging Distributed Systems.
Challenges and options for validation and debugging.
The accepted wisdom does not always hold true.
Lunchtime doubly so. - Ford Prefect to Arthur Dent in "The Hitchhiker's Guide to the Galaxy", by Douglas Adams.
Elios | Sat, 07 Nov 2018 09:29:52 UTC.
Thanks for the nice post. That's a great sum-up of problems in the design and implementation of distributed low latency systems.
I'm working on a distributed low-latency market data distribution system. In this system, one of the biggest challenge is how to measure its latency which is supposed to be several micro seconds.
In our previous system, the latency is measured in an end-to-end manner. We take timestamp in milli seconds on both publisher and subscriber side and record the difference between them. This works but we are aware that the result is not accurate because even with servers having clock synchronized with NTP, users complain sometimes that negative latency is observed.
Given we are reducing the latency to micro seconds, the end-to-end measurement seems to be too limited (it should be better with PTP but we can't force our users to support PTP in their infrastructure) and thus we are trying to get a round-trip latency. However, I can see immediately several cons with this method :
- extra complexity to configure and implement the system because we need to ensure two-way communication. - we can't deduce the end-to-end latency from the round trip one because the loads on both direction are not the same. (we want to send only some probes and get them back)
Do you have some experiences on the round-trip latency measurement and if so could you please share some best practices ?

No comments:

Post a Comment