यह आम लिस्प फ़ंक्शन, जो कि दीवार के वायरफ्रेम किनारों के चार सिरों की गणना करता है, जिसमें बेहद सरल किंडरगार्टन-स्तर अंकगणित और कुछ 'केस' परीक्षण गतिशील रूप से 1 9 6608 बाइट प्रति रेंडर फ्रेम आवंटित करने के लिए जिम्मेदार प्रतीत होते हैं; एसबीसीएल का प्रोफाइलर मुझे बताता है कि यह मेरा सबसे समस्याग्रस्त कार्य है जहां तक विपक्ष जाता है। मैं जो काम कर रहा हूं उसके बारे में एक सामान्य विचार देने के लिए, यह एक छोटा पहला व्यक्ति डंगऑन क्रॉलर गेम है, और एक कालकोठरी बिल्कुल 32x32 कोशिकाएं होती है, और प्रत्येक कक्ष में 4 दीवारें होती हैं। 32 * 32 * 4 * एक्स = 1 9 6608, और इसलिए एक्स 48 हो गया है, जो 4 * 12 (4 दीवारें * 12 फ्लोट प्रति दीवार हो सकता है? शायद नहीं)।इस आम लिस्प समारोह में "रहस्य-consing" को खत्म करना?
अब, मैं गेमप्ले मोड के भीतर ओपनजीएल डिस्प्ले सूचियों का उपयोग कर इस प्रदर्शन समस्या को आसानी से कम कर सकता हूं, और मुझे लगता है कि मैं आगे बढ़ूंगा और करूंगा। फिर भी, 1) मैं आम तौर पर समय-समय पर अनुकूलन नहीं करता हूं, और अधिक महत्वपूर्ण बात यह है कि 2) मुझे अभी भी इस परेशानियों की तरह कुछ परेशानियों को छोड़ना पसंद नहीं है, और मुझे आश्चर्य है कि मैं और क्या कर सकता था।
'गति' के लिए 'अनुकूलन' के लिए एक 'घोषित' कर रहा:
(defun calculate-wall-points (x y wall) (declare (integer x y) (keyword wall)) "Return the 4 vertices (12 floats) of a given dungeon cell wall" (let ((xf (coerce x 'float)) (yf (coerce y 'float))) (case wall (:SOUTH (values xf yf 0.0 (1+ xf) yf 0.0 (1+ xf) yf 1.0 xf yf 1.0)) (:WEST (values xf yf 0.0 xf yf 1.0 xf (1+ yf) 1.0 xf (1+ yf) 0.0)) (:NORTH (values xf (1+ yf) 0.0 xf (1+ yf) 1.0 (1+ xf) (1+ yf) 1.0 (1+ xf) (1+ yf) 0.0)) (:EAST (values (1+ xf) (1+ yf) 0.0 (1+ xf) (1+ yf) 1.0 (1+ xf) yf 1.0 (1+ xf) yf 0.0)) (otherwise (error "Not a valid heading passed for wall in function calculate-wall-points: ~A" wall)))))
चीजें मैं इसे ठीक करने की कोशिश की है की एक जोड़ी संक्षेप में: मेरा समारोह के रूप में-है, इस प्रकार है 3 पर और 0 पर सब कुछ (इस समारोह में, साथ ही एकमात्र फ़ंक्शन जो इसे कॉल करता है)। आश्चर्यजनक रूप से, प्रोफाइलर ने इस समारोह की रिपोर्ट थोड़ी कम पेशकश की ... लेकिन यह अभी भी cons cons। मैं शून्य-consing के लिए लक्ष्य कर रहा हूँ। अंकगणित विपक्ष नहीं होना चाहिए।
तब मैंने सोचा कि 'मूल्य' यह कर रहे हैं। शायद, मैंने सोचा, यह आंतरिक रूप से केवल 'सूची' की तरह कुछ है, जो बिना किसी संदेह के, conses (ब्रह्मांड में 'सूची' फ़ंक्शन का एकमात्र उद्देश्य है)। इसे कम करने की कोशिश करने के लिए मैंने क्या किया? बस प्रयोग के लिए, मैंने फ़ाइल को एक दीवार-वर्टेक्स-बफर ग्लोबल सरणी बनाने के लिए संशोधित किया, आकार के फ्लोट के 12 तत्वों को फिट करने के लिए आकार दिया, और इसे संशोधित करने के लिए इस फ़ंक्शन को संशोधित किया, और कॉलिंग फ़ंक्शन इसके बाद से पढ़ने के लिए इस फ़ंक्शन को कॉल करना (इसलिए यह लगातार किसी भी स्थान को आवंटित करने के बजाय स्मृति में उसी स्थान पर रखे 12 फ्लोट्स का एक सेट सेट करेगा)। आश्चर्य की बात है, इसने इस समारोह को एक विपक्षी-पिग्गी होने से नहीं रोका! तो ... 'मामला' कर रहा था? मुझे यह दिलचस्प लगता है कि, पहले उल्लेख किया गया था कि रहस्य संख्या 48 थी। 48 = 4 * 12, शायद उन 4 केस परीक्षण 12 फ्लोट प्रति 'मूल्य' कॉल के समय। या, यह एक संयोग हो सकता है, जिसमें 48 बाइट्स का अर्थ कुछ और है (चूंकि एक फ्लोट 1 बाइट नहीं है, मुझे संदेह है कि यह कुछ और है)। यह महत्वपूर्ण लगता है, लेकिन मैं अपने सिर को लपेट नहीं सकता कि मेरे अगले दृष्टिकोण क्या हो।
'मामले' को 'cond' समकक्ष के साथ बदलने की कोशिश की, बस इस बिंदु पर स्ट्रॉ के लिए grasping, कुछ भी नहीं किया।
तो यह कार्य कहां से "रहस्य consing" आ सकता है? आप एक और समस्या के इस मुश्किल gremlin दृष्टिकोण से अधिक अनुभवी लिस्प प्रोग्रामर कैसे अनुभव करेंगे?
(EDIT) @FheheemMitha के लिए, वह कार्य है जो गणना-दीवार-बिंदु फ़ंक्शन का उपयोग करता है; कि परेशानी समारोह बाद में साथ inlined गया था (सुचना (इनलाइन गणना दीवार-अंक)) बस से पहले की गणना दीवार-अंक की परिभाषा:
(defun render-dungeon-room (dungeon-object x y)
(declare (optimize (speed 3) (space 0) (debug 0)))
(declare (type fixnum x y))
(let ((cell (cell-at dungeon-object x y)))
(unless (null cell)
(dolist (wall-heading +basic-headings+)
(unless (eq wall-heading (opposite-heading *active-player-heading*))
(when (eql (get-wall-type cell wall-heading) :NORMAL)
(multiple-value-bind (v1x v1y v1z v2x v2y v2z v3x v3y v3z v4x v4y v4z)
(calculate-wall-points x y wall-heading)
(declare (type float v1x v1y v1z v2x v2y v2z v3x v3y v3z v4x v4y v4z))
(gl:with-primitive :quads
(if (is-edit-mode)
(case wall-heading
(:NORTH
(gl:color 0.4 0.4 0.4))
(:WEST
(gl:color 0.4 0.0 0.0))
(:SOUTH
(gl:color 0.0 0.0 0.4))
(:EAST
(gl:color 0.0 0.4 0.0)))
(gl:color 0.1 0.1 0.1))
(gl:vertex (the float v1x)
(the float v1y)
(the float v1z))
(gl:vertex (the float v2x)
(the float v2y)
(the float v2z))
(gl:vertex (the float v3x)
(the float v3y)
(the float v3z))
(gl:vertex (the float v4x)
(the float v4y)
(the float v4z)))
(gl:color 1.0 1.0 1.0)
(gl:with-primitive :line-loop
(gl:vertex (the float v1x)
(the float v1y)
(the float v1z))
(gl:vertex (the float v2x)
(the float v2y)
(the float v2z))
(gl:vertex (the float v3x)
(the float v3y)
(the float v3z))
(gl:vertex (the float v4x)
(the float v4y)
(the float v4z)))))))))
शून्य)
धन्यवाद उत्पन्न निरीक्षण कर सकते हैं - मैं होता संदिग्ध कभी नहीं किया है कि चल बिन्दु संख्या सब बातों की,, अपराधी थे (मैं काफी पकड़ा एक समुद्री भोजन रेस्तरां खोलने के लिए लाल बालियां)। अब यह जानने के लिए कि बेहतर तरीके से क्या देखना है, मैंने एसबीसीएल के मैनुअल के चारों ओर खोद दिया और यह उल्लेख किया कि 'इनलाइन' फ्लोट-भारी कार्यों को अस्वीकार करने से बेहतर प्रदर्शन मिलेगा। यह काम करने लग रहा था; अब इस फ़ंक्शन में कॉलिंग फ़ंक्शन के साथ-साथ कॉलिंग फ़ंक्शन (जो, मुझे लगता है, अब आंतरिक रूप से उसी फ़ंक्शन में पोस्ट किया गया है, बाद में संकलन) में शून्य संवेदना चल रही है। – valq
@valq: नमस्ते। मुझे फ़ंक्शन विवाद रोकने के लिए आपने जो किया है, उसके विवरण में रूचि है। क्या आप प्रश्न में या एक अलग उत्तर के रूप में, अपने पूर्व और पोस्ट अनुकूलन कोड के उदाहरण पोस्ट कर सकते हैं? धन्यवाद। –
@ फेहेम मिथा एक ऐसा करने के बाद बहुत कुछ (अस्वीकरण (इनलाइन गणना-दीवार-बिंदु)), मुझे याद है कि मैंने इसके बीच प्रोफाइलर में और कम से कम उस कार्य को उपयोग करने के लिए देखा है (उपयोग)। मैं उस कोड को कोड पोस्ट करूंगा जो इसे एक अलग उत्तर में इस्तेमाल करता है। मुझे नहीं पता कि आपको इसके साथ गड़बड़ करने के लिए और भी कोड की आवश्यकता होगी, क्योंकि यह इसके कार्यक्षेत्र से परे कुछ कार्यों और वैश्विक चरों का भी संदर्भ देता है। – valq