के साथ यूडीपी पैकेट का रीयलटाइम प्राप्त करना मेरे पास एक स्रोत है जो मेरी क्यूएनएक्स न्यूट्रीनो मशीन पर 819.2 हर्ट्ज (~ 1.2 एमएमएस) की दर से यूडीपी पैकेट भेजता है। मैं उन संदेशों को जितना संभव हो उतना देरी और जिटर के साथ प्राप्त करना और संसाधित करना चाहता हूं।क्यूएनएक्स आरटीओएस
मेरा पहला कोड मूल रूप से किया गया था:
SetupUDPSocket();
while (true) {
recv(socket, buffer, BufferSize, MSG_WAITALL); // blocks until whole packet is received
processPacket(buffer);
}
समस्या यह है कि recv() केवल प्रणाली के प्रत्येक घड़ी टिक पर जांच है अगर वहाँ एक नया पैकेट उपलब्ध है। टाइमर टिक आमतौर पर 1ms है। इसलिए, यदि मैं इसका उपयोग करता हूं तो मुझे एक बड़ा जिटर मिलेगा, क्योंकि मैं प्रत्येक 1ms या प्रत्येक 2ms में एक पैकेट को संसाधित करता हूं। मैं टाइमर टिक के आकार को रीसेट कर सकता था, लेकिन यह पूरे सिस्टम को प्रभावित करेगा (और अन्य प्रक्रियाओं के अन्य टाइमर, आदि)। और मैं अभी भी एक जिटर होगा, क्योंकि मैं निश्चित रूप से कभी भी 819.2 हर्ट्ज से मेल नहीं खाऊंगा।
तो, मैंने नेटवर्क कार्ड की इंटरप्ट लाइन (5) का उपयोग करने की कोशिश की। लेकिन ऐसा लगता है कि अन्य चीजें भी हैं जो बाधा उत्पन्न करने का कारण बनती हैं। मैं निम्नलिखित कोड के लिए इस्तेमाल किया:
ThreadCtl(_NTO_TCTL_IO, 0);
SIGEV_INTR_INIT(&event);
iID = InterruptAttachEvent(IRQ5, &event, _NTO_INTR_FLAGS_TRK_MSK);
while(true) {
if (InterruptWait(0, NULL) == -1) {
std::cerr << "errno: " << errno << std::endl;
}
length = recv(socket, buffer, bufferSize, 0); // non-blocking this time
LogTimeAndLength();
InterruptUnmask(IRQ5, iID;
}
यह शुरुआत में एक भी सफल पढ़ने में परिणाम है, का पालन किया 0 समय पास करने के बाद साथ 0 बाइट लंबाई पढ़ता द्वारा। ऐसा लगता है कि InterruptUnmask() के बाद, InterruptWait() बिल्कुल इंतजार नहीं करता है, इसलिए पहले से ही एक नया बाधा होना चाहिए (या वही ?!)।
क्या नेटवर्क कार्ड की इंटरप्ट लाइन के साथ ऐसा कुछ करना संभव है? क्या 819.2 हर्ट्ज की दर से पैकेट प्राप्त करने के लिए कोई अन्य संभावनाएं हैं?
नेटवर्क कार्ड के बारे में कुछ जानकारी: 'पीसीआई -vvv' आउटपुट:
Class = Network (Ethernet)
Vendor ID = 8086h, Intel Corporation
Device ID = 107ch, 82541PI Gigabit Ethernet Controller
PCI index = 0h
Class Codes = 020000h
Revision ID = 5h
Bus number = 4
Device number = 15
Function num = 0
Status Reg = 230h
Command Reg = 17h
I/O space access enabled
Memory space access enabled
Bus Master enabled
Special Cycle operations ignored
Memory Write and Invalidate enabled
Palette Snooping disabled
Parity Error Response disabled
Data/Address stepping disabled
SERR# driver disabled
Fast back-to-back transactions to different agents disabled
Header type = 0h Single-function
BIST = 0h Build-in-self-test not supported
Latency Timer = 40h
Cache Line Size= 8h un-cacheable
PCI Mem Address = febc0000h 32bit length 131072 enabled
PCI Mem Address = feba0000h 32bit length 131072 enabled
PCI IO Address = ec00h length 64 enabled
Subsystem Vendor ID = 8086h
Subsystem ID = 1376h
PCI Expansion ROM = feb80000h length 131072 disabled
Max Lat = 0ns
Min Gnt = 255ns
PCI Int Pin = INT A
Interrupt line = 5
CPU Interrupt = 5h
Capabilities Pointer = dch
Capability ID = 1h - Power Management
Capabilities = c822h - 28002000h
Capability ID = 7h - PCI-X
Capabilities = 2h - 400000h
Device Dependent Registers:
0x040: 0000 0000 0000 0000 0000 0000 0000 0000
...
0x0d0: 0000 0000 0000 0000 0000 0000 01e4 22c8
0x0e0: 0020 0028 0700 0200 0000 4000 0000 0000
0x0f0: 0500 8000 0000 0000 0000 0000 0000 0000
और 'nicinfo' आउटपुट:
wm1:
INTEL 82544 Gigabit (Copper) Ethernet Controller
Physical Node ID ........................... 000E0C C5F6DD
Current Physical Node ID ................... 000E0C C5F6DD
Current Operation Rate ..................... 100.00 Mb/s full-duplex
Active Interface Type ...................... MII
Active PHY address ....................... 0
Maximum Transmittable data Unit ............ 1500
Maximum Receivable data Unit ............... 0
Hardware Interrupt ......................... 0x5
Memory Aperture ............................ 0xfebc0000 - 0xfebdffff
Promiscuous Mode ........................... Off
Multicast Support .......................... Enabled
पढ़ने के लिए धन्यवाद!
'समस्या यह है कि recv() केवल एक नया पैकेट होने पर सिस्टम के प्रत्येक टाइमर टिक पर जांचता है उपलब्ध '- ऐसा क्यों होगा? मुझे कोई क्यूएनएक्स नहीं पता, - क्या नेटवर्क चालक सैनि से काम नहीं करता है? इंटरप्ट ड्राइवर को एक ईवेंट/सेमफोर सेट करना चाहिए और ओएस के माध्यम से बाहर निकलना चाहिए ताकि यह recv() थ्रेड को 'तत्काल' तैयार कर सके। किसी भी 'टाइमर टिक तक प्रतीक्षा करें' की आवश्यकता नहीं होनी चाहिए - यह सिर्फ निराशाजनक है - साथ ही सहकारी मतदान लूप का भी उपयोग कर सकता है :( –
मार्टिन जैसे कार्यान्वयन विवरण ड्राइवर और यहां तक कि कार्ड के विशिष्ट मॉडल के साथ भिन्न हो सकते हैं, लेकिन आपने नहीं किया है सूचीबद्ध या तो –
@ मार्टिनजेम्स और बेन वोगेट: क्षमा करें, मुझे इस तथ्य से अवगत नहीं था कि मेरी समस्या ड्राइवर से संबंधित हो सकती है। 'निकिनोफो' का कहना है, "इंटेल 82544 गिगाबिट (कॉपर) ईथरनेट कंट्रोलर" और 'पीसीआई-वीवीवी' आउटपुट " विक्रेता आईडी = 8086 एच, इंटेल कॉर्पोरेशन डिवाइस आईडी = 107ch, 82541PI गिगाबिट ईथरनेट कंट्रोलर " – jan