का उपयोग करने से धीमा है अब तक मैं अपने प्रोजेक्ट में std::queue
का उपयोग कर रहा था। मैंने औसत समय को मापा जो इस कतार पर एक विशिष्ट संचालन की आवश्यकता है।Boost.Lockfree कतार का उपयोग म्यूटेक्स
बार 2 मशीनों पर मापा गया था: मेरा स्थानीय उबंटू वीएम और रिमोट सर्वर। std::queue
का उपयोग करके, औसत मशीनों पर लगभग समान था: ~ 750 माइक्रोसॉन्ड।
फिर मैंने std::queue
से boost::lockfree::spsc_queue
पर "अपग्रेड किया", इसलिए मैं कतार की रक्षा करने वाले म्यूटेक्स से छुटकारा पा सकता हूं। मेरे स्थानीय वीएम पर मैं एक बड़ा प्रदर्शन लाभ देख सकता था, औसत अब 200 माइक्रोसॉन्ड पर है। रिमोट मशीन पर हालांकि, औसत 800 माइक्रोसॉन्ड तक चला गया, जो इससे पहले धीमा है।
सबसे पहले मैंने सोचा था कि इस वजह से रिमोट मशीन ताला मुक्त कार्यान्वयन का समर्थन नहीं कर सकते हैं हो सकता है:
से नहीं सभी हार्डवेयर परमाणु निर्देश के एक ही सेट का समर्थन करता है। यदि यह हार्डवेयर में उपलब्ध नहीं है, तो इसे गार्ड का उपयोग करके सॉफ्टवेयर में नकल किया जा सकता है। हालांकि इसमें लॉक-मुक्त संपत्ति खोने की स्पष्ट कमी है।
यह जानने के लिए इन निर्देशों का समर्थन कर रहे, boost::lockfree::queue
एक विधि bool is_lock_free(void) const;
कहा जाता है। हालांकि, boost::lockfree::spsc_queue
में ऐसा कोई फ़ंक्शन नहीं है, जो मेरे लिए, इसका तात्पर्य है कि यह हार्डवेयर पर भरोसा नहीं करता है और यह किसी भी मशीन पर हमेशा लॉकफ्री होता है।
प्रदर्शन हानि का कारण क्या हो सकता है?
exmple कोड (निर्माता/उपभोक्ता)
// c++11 compiler and boost library required
#include <iostream>
#include <cstdlib>
#include <chrono>
#include <async>
#include <thread>
/* Using blocking queue:
* #include <mutex>
* #include <queue>
*/
#include <boost/lockfree/spsc_queue.hpp>
boost::lockfree::spsc_queue<int, boost::lockfree::capacity<1024>> queue;
/* Using blocking queue:
* std::queue<int> queue;
* std::mutex mutex;
*/
int main()
{
auto producer = std::async(std::launch::async, [queue /*,mutex*/]()
{
// Producing data in a random interval
while(true)
{
/* Using the blocking queue, the mutex must be locked here.
* mutex.lock();
*/
// Push random int (0-9999)
queue.push(std::rand() % 10000);
/* Using the blocking queue, the mutex must be unlocked here.
* mutex.unlock();
*/
// Sleep for random duration (0-999 microseconds)
std::this_thread::sleep_for(std::chrono::microseconds(rand() % 1000));
}
}
auto consumer = std::async(std::launch::async, [queue /*,mutex*/]()
{
// Example operation on the queue.
// Checks if 1234 was generated by the producer, returns if found.
while(true)
{
/* Using the blocking queue, the mutex must be locked here.
* mutex.lock();
*/
int value;
while(queue.pop(value)
{
if(value == 1234)
return;
}
/* Using the blocking queue, the mutex must be unlocked here.
* mutex.unlock();
*/
// Sleep for 100 microseconds
std::this_thread::sleep_for(std::chrono::microseconds(100));
}
}
consumer.get();
std::cout << "1234 was generated!" << std::endl;
return 0;
}
कृपया एक [mcve] जोड़ने पर विचार करें जो आपके प्रदर्शन माप को पुन: पेश करने की अनुमति देता है। इससे अधिक व्यावहारिक उत्तर की अनुमति मिल जाएगी। – Zulan
इस प्रश्न में उच्च रुचि को देखते हुए, यह वास्तव में दुर्भाग्यपूर्ण है कि दो अलग-अलग प्रणालियों पर प्रदर्शन विसंगति के मूल पहलू का उत्तर नहीं दिया जा सकता है। मुझे लगता है कि प्रश्न में सुधार होने पर एक विशिष्ट व्यावहारिक उत्तर के लिए और अधिक संभावनाएं हैं। – Zulan
@Zulan मैं जल्द ही एक ठोस उदाहरण जोड़ने की कोशिश करूंगा। – Bobface