कम विलंबता यूनिक्स / लिनक्स


11

अधिकांश कम विलंबता / उच्च आवृत्ति प्रोग्रामिंग नौकरियां (नौकरी के चश्मे के आधार पर) यूनिक्स प्लेटफार्मों पर लागू की जाती हैं। बहुत सारे स्पेक्स में वे "लो लेटेंसी लिनेक्स" प्रकार के अनुभव वाले लोगों के लिए विशेष अनुरोध करते हैं।

यह मानते हुए कि एक वास्तविक समय लिनक्स ओएस का मतलब नहीं है, क्या लोग मुझे इस बात का समर्थन कर सकते हैं कि यह क्या हो सकता है? मुझे पता है कि आप थ्रेड्स के लिए सीपीयू आत्मीयता सेट कर सकते हैं, लेकिन मैं मान रहा हूं कि वे इससे बहुत अधिक मांग रहे हैं।

कर्नेल ट्यूनिंग? (हालांकि मैंने सुना है कि सोलरफेयर जैसे निर्माता कर्नेल बाईपास नेटवर्क कार्ड का उत्पादन करते हैं)?

DMA या संभवतः प्रक्रियाओं के बीच साझा की गई मेमोरी के बारे में क्या? अगर लोग मुझे संक्षिप्त विचार दे सकते हैं तो मैं Google पर शोध कर सकता हूं।

(इस सवाल के लिए शायद उच्च आवृत्ति ट्रेडिंग से परिचित किसी व्यक्ति की आवश्यकता होगी)


2
कर्नेल ट्यूनिंग गैर-रीयल-टाइम ओएस को वास्तविक समय के रूप में बनाने का तरीका है। थ्रेड पिनिंग भी अनिवार्य है। आप इस लेख में इसके बारे में और अधिक पढ़ सकते हैं: coralblocks.com/index.php/2014/04/…
rdalmeida

इसके अलावा संबंधित: stackoverflow.com/q/15702601/632951
पचेरियर

जवाबों:


26

मैंने आईबी और हेज फंड सेटिंग्स में एचएफटी समूहों का समर्थन करने वाले काम की एक उचित मात्रा में किया है। मैं sysadmin दृष्टिकोण से जवाब देने जा रहा हूं, लेकिन यह कुछ इस तरह के वातावरण में भी प्रोग्रामिंग पर लागू होता है।

कुछ चीजें हैं जो नियोक्ता आमतौर पर "लो लेटेंसी" समर्थन को संदर्भित करते हैं। इनमें से कुछ "कच्ची गति" प्रश्न हैं (क्या आप जानते हैं कि किस प्रकार का 10 जी कार्ड खरीदना है, और इसे किस स्लॉट में डालना है?), लेकिन उनमें से अधिक उन तरीकों के बारे में हैं जिनमें एक पारंपरिक से उच्च आवृत्ति ट्रेडिंग वातावरण भिन्न होता है? यूनिक्स का वातावरण। कुछ उदाहरण:

  • यूनिक्स पारंपरिक रूप से संसाधनों के लिए उनमें से किसी को भूखा रखे बिना बड़ी संख्या में प्रक्रियाओं का समर्थन करने के लिए तैयार है, लेकिन एचएफटी वातावरण में, आप संदर्भ स्विचिंग के लिए एक न्यूनतम ओवरहेड के साथ एक आवेदन चलाना चाहते हैं , और इसी तरह। एक क्लासिक छोटे उदाहरण के रूप में, इंटेल सीपीयू पर हाइपरथ्रेडिंग चालू करने से अधिक प्रक्रियाएं एक ही बार में चलने की अनुमति मिलती हैं - लेकिन उस गति पर एक महत्वपूर्ण प्रदर्शन प्रभाव पड़ता है जिस पर प्रत्येक व्यक्तिगत प्रक्रिया को निष्पादित किया जाता है। एक प्रोग्रामर के रूप में, आप इसी तरह थ्रेडिंग और आरपीसी जैसे अमूर्त की लागत को देखते जा रहे हैं, और यह पता लगा सकते हैं कि एक अधिक अखंड समाधान - जबकि कम स्वच्छ - ओवरहेड से बचना होगा।

  • टीसीपी / आईपी को आमतौर पर कनेक्शन ड्रॉप को रोकने और बैंडविड्थ के कुशल उपयोग को उपलब्ध करने के लिए ट्यून किया जाता है। यदि आपका लक्ष्य सबसे तेज़ लिंक से सबसे कम विलंबता को प्राप्त करना है - तो अधिक विवश लिंक से बाहर उच्चतम बैंडविड्थ को प्राप्त करने के बजाय - आप नेटवर्क स्टैक के ट्यूनिंग को समायोजित करना चाहते हैं। एक प्रोग्रामिंग साइड से, आप इसी तरह उपलब्ध सॉकेट विकल्पों को देखना चाहेंगे, और यह पता लगाएंगे कि विलंबता को कम करने के लिए बैंडविड्थ और विश्वसनीयता के लिए कौन से चूक अधिक हैं।

  • नेटवर्किंग के साथ, इसलिए स्टोरेज के साथ - आप जानना चाहते हैं कि एप्लिकेशन प्रॉब्लम से स्टोरेज परफॉर्मेंस की समस्या को कैसे बताया जाए, और यह जानें कि I / O उपयोग के कौन से पैटर्न आपके प्रोग्राम के प्रदर्शन के साथ हस्तक्षेप करने की कम से कम संभावना है (एक के रूप में उदाहरण के लिए, सीखें कि अतुल्यकालिक IO का उपयोग करने की जटिलता आपके लिए भुगतान कैसे कर सकती है, और डाउनसाइड क्या हैं)।

  • अंत में, और अधिक दर्दनाक रूप से: हम यूनिक्स के प्रवेश की स्थिति के बारे में अधिक जानकारी चाहते हैं क्योंकि हम यथासंभव निगरानी करते हैं, इसलिए हम एसएनएमपी एजेंट जैसे उपकरण चलाना पसंद करते हैं, नागोस जैसे सक्रिय निगरानी उपकरण और सर (1) जैसे डेटा एकत्र करने वाले उपकरण। ऐसे वातावरण में जहां संदर्भ स्विच को पूरी तरह से कम से कम करने की आवश्यकता होती है और डिस्क और नेटवर्क IO का उपयोग कसकर नियंत्रित किया जाता है, हालांकि, हमें निगरानी के खर्च और निगरानी वाले बक्से के नंगे-धातु प्रदर्शन के बीच सही व्यापार ढूंढना होगा। इसी तरह, आप किन तकनीकों का उपयोग कर रहे हैं जो कोडिंग को आसान बनाते हैं लेकिन क्या आपको प्रदर्शन में लागत आ रही है?

अंत में, अन्य चीजें हैं जो बस समय के साथ आती हैं; ट्रिक्स और विवरण जो आप अनुभव के साथ सीखते हैं। लेकिन ये अधिक विशिष्ट हैं (जब मैं एपोल का उपयोग करता हूं? सैद्धांतिक रूप से समान PCIe नियंत्रकों के साथ HP सर्वर के दो मॉडल इतने अलग तरीके से क्यों करते हैं?), जो कुछ भी आपकी विशिष्ट दुकान का उपयोग कर रहा है उससे अधिक बंधा हुआ है, और एक वर्ष से दूसरे वर्ष में बदलने की अधिक संभावना है? ।


1
धन्यवाद, हालांकि मुझे एक प्रोग्रामिंग जवाब में दिलचस्पी थी यह बहुत उपयोगी और जानकारीपूर्ण था।
user997112

5
@ user997112 यह एक प्रोग्रामिंग उत्तर है। यह इस तरह के रूप प्रतीत नहीं होता है, तो इसे पढ़ने जब तक यह होता है :) रख
टिम पोस्ट

15

@Jimwise से उत्कृष्ट हार्डवेयर / सेटअप ट्यूनिंग उत्तर के अलावा, "कम विलंबता लिनक्स" का अर्थ है:

  • नियतात्मकता के कारणों के लिए C ++ (जीसी किक के दौरान कोई आश्चर्य की बात नहीं है), निम्न-स्तरीय सुविधाओं (I / O, सिग्नल), भाषा शक्ति (TMP और STL का पूर्ण उपयोग, प्रकार सुरक्षा) तक पहुंच।
  • गति-ओवर-मेमोरी पसंद करें:> 512 जीबी रैम आम है; डेटाबेस इन-मेमोरी, कैश्ड अप-फ्रंट या एक्सक्लूसिव नोएसक्यूएल उत्पाद हैं।
  • एल्गोरिथ्म विकल्प: जैसे-फास्ट-एज़-संभव-बनाम बनाम सेंस / समझने योग्य / एक्स्टेंसिबल, जैसे लॉक-फ़्री, ऐर-ऑफ-ऑब्जेक्ट्स-बूल-प्रॉपर्टीज़ के बजाय कई बिट एरेज़।
  • विभिन्न कोर पर प्रक्रियाओं के बीच साझा मेमोरी जैसी ओएस सुविधाओं का पूर्ण उपयोग।
  • सुरक्षित। HFT सॉफ्टवेयर आमतौर पर स्टॉक एक्सचेंज में सह-स्थित होता है इसलिए मैलवेयर संभावनाएं अस्वीकार्य हैं।

इनमें से कई तकनीकों में गेम के विकास के साथ ओवरलैप है जो एक कारण है कि वित्तीय सॉफ्टवेयर उद्योग किसी भी हाल ही में निरर्थक गेम प्रोग्रामर को अवशोषित करता है (कम से कम जब तक वे अपने किराए के बकाया का भुगतान नहीं करते हैं)।

अंतर्निहित डेटा को बाजार के डेटा की बहुत उच्च बैंडविड्थ स्ट्रीम जैसे सुरक्षा (स्टॉक, कमोडिटीज़, एफएक्स) की कीमतों को सुनने में सक्षम होना है और फिर सुरक्षा के आधार पर बहुत तेज़ खरीद / बिक्री / कुछ भी निर्णय नहीं करना है। और वर्तमान होल्डिंग्स।

बेशक, यह सब शानदार रूप से गलत हो सकता है।


तो मैं बिट सरणियों बिंदु पर विस्तृत करूँगा । मान लीजिए कि हमारे पास एक उच्च आवृत्ति ट्रेडिंग सिस्टम है जो ऑर्डर की लंबी सूची (5k आईबीएम खरीदें, 10k डेल बेचें आदि) पर संचालित होता है। मान लें कि हमें यह निर्धारित करने की आवश्यकता है कि क्या सभी आदेश भरे गए हैं, ताकि हम अगले कार्य पर जा सकें। पारंपरिक OO प्रोग्रामिंग में, यह दिखने वाला है:

class Order {
  bool _isFilled;
  ...
public:
  inline bool isFilled() const { return _isFilled; }
};

std::vector<Order> orders;
bool needToFillMore = std::any_of(orders.begin(), orders.end(), 
  [](const Order & o) { return !o.isFilled(); } );

इस कोड की एल्गोरिथम जटिलता ओ (एन) होने जा रही है क्योंकि यह एक रैखिक स्कैन है। आइए मेमोरी एक्सेस के संदर्भ में प्रदर्शन प्रोफ़ाइल पर एक नज़र डालते हैं: std के अंदर लूप का प्रत्येक पुनरावृत्ति :: any_of () o.isFilled () कॉल करने जा रहा है, जो इनबिल्ड है, इसलिए _isFilled की मेमोरी एक्सेस बन जाती है, 1 बाइट (या 4 अपने आर्किटेक्चर, कंपाइलर और कंपाइलर सेटिंग्स पर निर्भर करते हुए) चलो एक वस्तु में 128 बाइट्स कुल कहते हैं। इसलिए हम प्रत्येक 128 बाइट्स में 1 बाइट एक्सेस कर रहे हैं। जब हम 1 बाइट पढ़ते हैं, तो सबसे खराब स्थिति को देखते हुए, हमें सीपीयू डेटा कैश मिस मिलेगा। यह रैम के लिए एक रीड रिक्वेस्ट का कारण बनेगा जो रैम से पूरी लाइन को पढ़ता है ( अधिक जानकारी के लिए यहां देखें ) सिर्फ 8 बिट्स को पढ़ने के लिए। तो मेमोरी एक्सेस प्रोफाइल एन के समानुपाती है।

इसके साथ तुलना करें:

const size_t ELEMS = MAX_ORDERS / sizeof (int);
unsigned int ordersFilled[ELEMS];

bool needToFillMore = std::any_of(ordersFilled, &ordersFilled[ELEMS+1],
   [](int packedFilledOrders) { return !(packedOrders == 0xFFFFFFFF); }

इस की मेमोरी एक्सेस प्रोफाइल, सबसे खराब स्थिति मानकर, एक रैम लाइन की चौड़ाई से विभाजित किया गया ELEMS (भिन्न होता है - दोहरे चैनल या ट्रिपल-चैनल, आदि हो सकता है)।

तो, वास्तव में, हम मेमोरी एक्सेस पैटर्न के लिए एल्गोरिदम का अनुकूलन कर रहे हैं। राम की कोई भी राशि मदद नहीं करेगी - यह सीपीयू डेटा कैश आकार है जो इस आवश्यकता का कारण बनता है।

क्या यह मदद करता है?


YouTube पर निम्न-विलंबता प्रोग्रामिंग (HFT के लिए) के बारे में एक उत्कृष्ट CPPCon बात है: https://www.youtube.com/watch?v=NH1Tta7purM


"सरणी-ऑफ़-ऑब्जेक्ट्स-बूल-प्रॉपर्टीज़ के बजाय कई बिट एरेज़" इससे आपका क्या मतलब है?
user997112

1
मैंने उदाहरण और लिंक के साथ विस्तार किया है।
JBRWilkinson

एक कदम आगे बढ़ते हुए - एक बाइट का उपयोग करने के बजाय यह इंगित करने के लिए कि क्या कोई ऑर्डर भरा है या नहीं - आप केवल एक बिट का उपयोग कर सकते हैं। तो एकल कैशलाइन (64 बाइट्स) में - आप 256 आदेशों की स्थिति का प्रतिनिधित्व कर सकते हैं। तो - कम याद आती है।
क्विकवर

इसके अलावा - यदि आप मेमोरी के रैखिक स्कैन कर रहे हैं - हार्डवेयर प्रीफ़ैचर आपके डेटा को लोड करने का एक बड़ा काम करता है। बशर्ते आप मेमोरी को क्रमिक रूप से या स्ट्राइडिंग या कुछ सरल तक पहुंचाएं। लेकिन अगर आप किसी भी तरह के गैर-अनुक्रमिक तरीके से मेमोरी एक्सेस कर रहे हैं - सीपीयू प्रीफ़ेचर गड़बड़ हो जाता है। जैसे एक द्विआधारी खोज। उस बिंदु पर प्रोग्रामर संकेत के साथ सीपीयू की मदद कर सकता है - _mm_prefetch।
क्विवर

-2

चूंकि मैंने उत्पादन में एक या दो उच्च आवृत्ति सॉफ्टवेयर नहीं डाले थे, इसलिए मैं सबसे महत्वपूर्ण बातें कहूंगा:

  1. नेटवर्किंग इंजीनियरों के साथ हार्डवेयर कॉन्फ़िगरेशन और सिस्टम प्रशासक, ट्रेडिंग सिस्टम द्वारा संसाधित किए गए आदेशों की संख्या के अच्छे परिणाम को परिभाषित नहीं करते हैं, लेकिन वे इसे बड़े समय तक डाउनग्रेड कर सकते हैं यदि वे ऊपर उल्लिखित मूल बातें नहीं जानते हैं।
  2. एकमात्र व्यक्ति जो वास्तव में उच्च आवृत्ति व्यापार करने के लिए सिस्टम बनाता है वह एक कंप्यूटर वैज्ञानिक है जो सी ++ में कोड को एक साथ रखता है

    उपयोग किए गए ज्ञान के बीच है

    A. तुलना और स्वैप संचालन।

    • कैसे प्रोसेसर में कैस का उपयोग किया जाता है और कंप्यूटर इसे नो-लॉकिंग स्ट्रक्चर प्रोसेसिंग के रूप में उपयोग करने के लिए कैसे सपोर्ट करता है। या ताला-मुक्त प्रसंस्करण। मैं यहां एक पूरी किताब लिखने नहीं जाऊंगा। संक्षेप में GNU संकलक और Microsoft संकलक CAS निर्देशों के प्रत्यक्ष उपयोग का समर्थन करते हैं। यह आपके कोड को कतार से तत्व निकालने या कतार में एक नया डालने के दौरान "No.Wair" के लिए अनुमति देता है।
  3. प्रतिभाशाली वैज्ञानिक अधिक उपयोग करेंगे। वह हाल ही में नए "पैटर्न" में मिल जाना चाहिए जो पहले जावा में दिखाई दिया था। डिस्प्रुटर पैटर्न कहा जाता है। यूरोप में LMAX एक्सचेंज में गुना ने उच्च आवृत्ति समुदाय को समझाया कि आधुनिक प्रोसेसर में थ्रेड-आधारित उपयोग सीपीयू द्वारा मेमोरी कैश रिलीज पर प्रसंस्करण समय को धीमा कर देगा, अगर दिन क्यू को आधुनिक सीपीयू कैश के आकार के साथ संरेखित नहीं किया जाता है = 64

    इसलिए उस रीडॉन के लिए उन्होंने एक जावा कोड सार्वजनिक किया जो मल्टी-थ्रेडिंग प्रक्रिया को हार्डवेयर सीपीयू कैश का उपयोग बिना संघर्ष समाधानों के सही तरीके से करने की अनुमति देता है। और अच्छा कंप्यूटर वैज्ञानिक यह जानने के लिए कि पैटर्न पहले से ही c ++ में पोर्ट किया गया था या खुद को पोर्ट कर रहा था।

    यह किसी भी व्यवस्थापक कॉन्फ़िगरेशन से परे एक प्रवीणता तरीका है। यह आज उच्च आवृत्ति के वास्तविक दिल में है।

  4. कंप्यूटर साइंस का लड़का बहुत सारे C ++ कोड लिखने के लिए न केवल QA लोगों की मदद करने के लिए है। लेकिन यह भी
    • व्यापारियों में मान्य चेहरा साबित गति प्राप्त की
    • निंदा करने के लिए विभिन्न पुरानी तकनीकों का इस्तेमाल किया और उन्हें अपने स्वयं के कोड के साथ उजागर करने के लिए दिखाया कि वे अच्छे परिणाम देने में विफल हैं
    • फिर से पुरानी प्रौद्योगिकियों का उपयोग करने के बजाय सिद्ध प्यूपे / चयन कर्नेल गति के आधार पर स्वयं के बहु-थ्रेडिंग संचार c ++ कोड लिखें। मैं यू उदाहरण दूंगा - आधुनिक टीसीपी पुस्तकालय आईसीई है। और लोगों ने जो किया वह उज्ज्वल है। लेकिन उनकी प्राथमिकताएं कई भाषाओं के साथ अनुकूलता के क्षेत्र में थीं। इसलिए। आप c ++ में बेहतर कर सकते हैं। तो ASYNCHRONOUS चुनिंदा कॉल के आधार पर उच्चतम प्रदर्शन छूट के लिए खोजें। और कई उपभोक्ताओं के लिए कई उत्पादकों के लिए मत जाओ - एचएफ के लिए नहीं।
      और आप यह जानकर आश्चर्यचकित होंगे कि पाइप का उपयोग केवल संदेश के कर्नेल अधिसूचना के लिए किया जाता है। आप 64-बिट संदेश संख्या को वहां रख सकते हैं - लेकिन सामग्री के लिए आप बिना किसी लॉकिंग कैस कतार में जाते हैं। अतुल्यकालिक कर्नेल select()कॉल द्वारा ट्रिगर ।
    • इसके अलावा। अपने धागे को c ++ थ्रेड एफिनिटी के साथ असाइन करने के बारे में जानें जो आपके संदेशों की पाइपिंग / कतारिंग करता है। उस धागे में कोर आत्मीयता होनी चाहिए। किसी और को एक ही सीपीयू कोर नंबर का उपयोग नहीं करना चाहिए।
    • और इसी तरह।

जैसा कि आप देख सकते हैं - उच्च आवृत्ति एक विकासशील फ़ेल्ड है। आप सफल होने के लिए सिर्फ C ++ प्रोग्रामर नहीं हो सकते।

और जब मैं सफल होने के लिए कहता हूं तो मेरा मतलब है कि आप जिस हेज फंड के लिए काम करेंगे, वह संख्या लोगों और नियोक्ताओं के बारे में वार्षिक मुआवजे में दौरे के प्रयासों को पहचानने के लिए काम करेगा।

सरल कंस्ट्रक्टर / डिस्ट्रक्टर एफएक्यू का समय हमेशा के लिए चला जाता है। और c ++… अपने आप को नए संकलकों के साथ माइग्रेशन प्रबंधन से राहत देने के लिए और कक्षाओं में बड़ी गहराई की कोई विरासत को लागू करने के लिए माइग्रेट करता है। समय की बर्बादी। कोड का पुन: उपयोग प्रतिमान बदल गया। यह सिर्फ यह नहीं है कि आपने बहुरूपियों में कितने वर्ग बनाए। यह कोड के सीधे पुष्टि किए गए समय प्रदर्शन के बारे में है जिसका आप पुन: उपयोग कर सकते हैं।

तो यह आपकी पसंद है कि आप वहां सीखने की अवस्था में जाएं, या नहीं। यह कभी भी स्टॉप साइन नहीं मारेगा।


6
आप वर्तनी और स्वरूपण में कुछ प्रयास करना चाह सकते हैं। अपने वर्तमान स्वरूप में, यह पद मुश्किल से समझ में आता है।
कोड्सचैचोस

1
आप 10 साल पहले की स्थिति का वर्णन करते हैं। हार्डवेयर आधारित समाधान आसानी से शुद्ध C ++ से बेहतर प्रदर्शन करते हैं आजकल, कोई फर्क नहीं पड़ता कि आपका C ++ कितना अनुकूलित है।
सोजेरड

उन लोगों के लिए जो जानना चाहते हैं कि हार्डवेयर आधारित समाधान क्या है - यह ज्यादातर FPGA समाधान है जहां कोड वास्तव में तेज मेमोरी में जला दिया जाता है और तथाकथित रोम मेमोरी के पलटाव को नहीं बदला जाता है। केवल पढ़ें
एलेक्स पी।

@alexp आप स्पष्ट रूप से नहीं जानते कि आप किस बारे में बात कर रहे हैं। FPGA "कोड से तेज़ मेमोरी में बर्न किया गया" कुछ अलग है।
Sjoerd
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.