2015-06-02 11 views
8

आप कुछ कार्यों के साथ एक मैट्रिक्स वर्ग बारे में मान लीजिए:गारंटी Temporary- की जांच> नामांकित अंक

class matrix 
{ 
public: 
    double operator()(size_t i, size_t j) const; 
    ... 
}; 

matrix operator*(const matrix &lhs, const matrix &rhs); 
... 

यह समझ में आता है कुछ मैट्रिक्स भाव के मूल्यांकन को स्थगित करने: M0 * एम 1 * एम 2 * एम 3 * m4 (जो चार operator* कॉल की श्रृंखला है) dynamic-programming matrix chain multiplication algorithm का उपयोग करने से लाभ प्राप्त कर सकते हैं; बहुत आम m0 * m1 टी में very efficient dgemm implementation है, और बहुत आगे है।

इसके परिणामस्वरूप जब तक इसकी आवश्यकता होती है तब तक वास्तविक गणना को स्थगित करने का भुगतान किया जाता है।

class matrix 
{ 
private: 
    /* 
    * Pointer to an abstract base class - either an actual matrix, 
    * or an expression tree. */ 
    std::shared_ptr<matrix_imp> m_imp; 

public: 
    // Forces compaction - 
    double operator()(size_t i, size_t j) const; 
    ... 
}; 

/* Lazy; creates a matrix with an expression tree using the 
* internals of lhs and rhs. */ 
matrix operator*(const matrix &lhs, const matrix &rhs); 
... 

प्रत्येक मैट्रिक्स एक आधार वर्ग वस्तु है कि एक जटिल अभिव्यक्ति पेड़ से एक असली मैट्रिक्स से रेंज कर सकते करने के लिए एक सूचक रखती है: यह करने के लिए ऊपर बदल जाता है। प्रत्येक ऑपरेशन आंतरिक कार्यान्वयन में सबसे अजीब परिवर्तन का उपयोग करके एक मैट्रिक्स बनाने की कोशिश करता है। कुछ परिचालनों में वास्तव में चीजों का मूल्यांकन करने, अभिव्यक्ति के पेड़ को कॉम्पैक्ट करने और वास्तविक कार्यान्वयन को वास्तविक मैट्रिक्स में सेट करने के अलावा कोई विकल्प नहीं होता है।


समस्या यह थी कि, व्यावहारिक रूप से, इसने बहुत आम मामलों में भारी मेमोरी ओवरहेड का कारण बना दिया। मान लीजिए कि आप एक फ़ाइल से पढ़ने के लिए एक लंबे और संकीर्ण मैट्रिक्स एक्स = एक्स पी एक्स क्ष, पी >> क्ष, स्टोर एक्स टी एक्स एक चर में, और एक्स त्यागने करते हैं। आलसी मूल्यांकन के साथ, स्मृति पीक्यू >> qq है। इन्हें लूप में लोड करें, और यह एक गंभीर समस्या है। (बेशक, क्लाइंट कोड द्वारा operator() पर कॉल करके प्रत्येक लोड के बाद कॉम्पैक्शन को मजबूर किया जा सकता है, लेकिन एल्गोरिदमिक औचित्य के बिना इसकी आवश्यकता होती है, बदसूरत और त्रुटि प्रवण है।)

प्रारंभ में, मैंने सोचा था कि चाल ctor स्वचालित compaction के लिए एक अच्छा बिंदु था - यह बिल्कुल बिंदु है जहां एक अस्थायी एक नामित वस्तु बन जाता है, और यह वस्तुओं है कि बढ़ती हुई स्मृति की खपत के कारण नाम दिया है, ताकि

matrix(matrix &&other); // <- Force compaction only here 

सब कुछ हल करने के लिए, उदाहरण के लिए,

auto res = // <- temp becoming named 
    a * // temp 
    b * // temp 
    c + // temp 
    2 * // temp 
    d; 

बू प्रकट होता टी पर गिना जा सकता है? जैसे, पर विचार

matrix load_xtx(const string &f_name) 
{ 
    matrix x = ... 
    return x.t() * x; 
} 

auto xtx = load_xtx("foo.hdf5"); // (*) 

संकलक (*) यह क्या करता है करने के लिए कुछ इसी तरह NRVO साथ में करने के लिए मना किया है, अर्थात् सिर्फ जगह में यह निर्माण करने के लिए? भले ही नहीं, एक संकलक अन्य मामलों में चीजों को अनुकूलित कर सकता है?

+1

मैट्रिक्स का उपयोग होने पर वास्तविक गणना करने के लिए यह आसान नहीं होगा, न केवल संग्रहीत किया जा सकता है? – Quentin

+0

@ क्वांटिन हां, लेकिन अगर मैं आपको सही ढंग से समझता हूं, तो यह वही है जो विशाल स्मृति ओवरहेड का कारण बनता है। मान लें कि आपके पास हजारों एक्स मैट्रिक्स लोड करने वाला लूप है, प्रत्येक को x टी एक्स में परिवर्तित करना - पहले पहुंच से पहले सभी (बिल्कुल परिदृश्य नहीं बनाया गया) - इस प्रकार की सामग्री सिस्टम को कचरा करने के लिए उपयोग की जाती है। –

+0

ओह, मैं देखता हूं। Quentin

उत्तर

2

चूंकि "आंतरिक सूचक" विधि स्थगित मूल्यांकन के लिए आवश्यक सभी लचीलापन नहीं दे सकती है, इसलिए सी ++ संख्यात्मक पुस्तकालयों द्वारा उपयोग किए जाने वाले सामान्य समाधान आलसी मूल्यांकन तंत्र को लागू करने वाले विशेष वर्गों को परिभाषित करना है। पुराना SO प्रश्न Lazy evaluation in C++ और इसके सर्वोत्तम उत्तर इस तरह के डिज़ाइन और कुछ नमूना कोड की मूल बातें दिखाते हैं।

हालांकि मैं एक विशेषज्ञ नहीं हूँ, मुझे लगता है कि इस वास्तुकला के अच्छे उदाहरण संख्यात्मक पुस्तकालयों Eigen (here some details about its implementation) और ब्लिट्ज ++, जो काफी हद तक टेम्पलेट्स पर निर्भर करता है (मैं अपनी आंतरिक illustrating वेब अद्यतन प्रलेखन पर भी नहीं मिला है, लेकिन this article हैं अपने इंजन के कुछ हिस्सों का वर्णन करता है और "अभिव्यक्ति टेम्पलेट" तकनीक का व्यापक अवलोकन भी प्रदान करता है)।

संबंधित मुद्दे