2017-02-16 10 views
5

में एक जटिल प्रोग्राम नहीं है जो एन के छोटे मानों के लिए std::array<double, N> का उपयोग करता है। यह इन arrays से मान प्राप्त करने के लिए operator[] का उपयोग करता है।जीसीसी कभी-कभी std :: array :: ऑपरेटर []

मुझे पता चला है कि -O2 या -O3 के साथ जीसीसी 6.1 इन कॉलों को इनलाइन नहीं करता है, जिससे इन सी ++ सरणी उनके सी समकक्षों की तुलना में धीमी होती हैं।

यहाँ उत्पन्न विधानसभा है:

340 <std::array<double, 8ul>::operator[](unsigned long) const>: 

340: 48 8d 04 f7    lea (%rdi,%rsi,8),%rax 
344: c3      retq 
345: 90      nop 
346: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 
34d: 00 00 00 

बहुत ही कोड सरणी के प्रत्येक आकार के लिए उत्सर्जित होता है (के बाद से वहाँ है कोई सीमा नहीं की जाँच)।

इस तरह के एक सरणी पर एक पाश इस तरह दिखता है:

4c0: e8 7b fe ff ff   callq 340 <std::array<double, 8ul>::operator[](unsigned long) const> 
4c5: be 07 00 00 00   mov $0x7,%esi 
4ca: 4c 89 f7    mov %r14,%rdi 
4cd: 48 89 44 24 78   mov %rax,0x78(%rsp) 

...6 more copies of this... 

4d2: e8 69 fe ff ff   callq 340 <std::array<double, 8ul>::operator[](unsigned long) const> 
4d7: 48 89 44 24 70   mov %rax,0x70(%rsp) 
4dc: 31 f6     xor %esi,%esi 
4de: 4c 89 ef    mov %r13,%rdi 

यह स्पष्ट रूप से बुरा लगता है। समस्या यह है कि छोटे परीक्षण कार्यक्रम इस व्यवहार को पूरा नहीं करते हैं।

तो मेरा सवाल यह है कि: मैं यह कहने के लिए जीसीसी कैसे प्राप्त कर सकता हूं कि यह इन निर्देशों को क्यों रेखांकित नहीं कर रहा है, और/या इसे इनलाइन बना देता है? जाहिर है, मैं __attribute__((inline)) जोड़ने के लिए <array> शीर्षलेख फ़ाइल को संशोधित नहीं कर सकता।

+4

जीसीसी के खिलाफ एक बग फाइल करें? – Brian

+1

@ ब्रायन: मुझे यकीन नहीं है कि यह एक बग है ... मुझे उम्मीद है कि जीसीसी में कुछ ह्युरिस्टिक यह सोच रहा है कि यह कोड किसी कारण से वास्तव में बेहतर है। यहां सवाल यह है कि मैं जीसीसी को बता सकता हूं कि यह क्या सोच रहा है, और/या उसे बदल सकता है। –

+1

लेकिन यदि आप एक बग फ़ाइल करते हैं, तो आप जीसीसी डेवलपर्स को यह समझाने के लिए प्राप्त कर सकते हैं। ;-) – Brian

उत्तर

2

जीसीसी 5 और 6 के अनुकूलक में एक बग प्रतीत होता है जो या संबंधित विकल्पों के साथ __attribute__(("unroll-loops")) का उपयोग करते समय प्रकट होता है।

आप यहाँ कार्रवाई में इसे देख सकते हैं: https://godbolt.org/g/ZBGCDB

इस कोड त्रुटि reproduces अगर आप -O3 -ffast-math साथ संकलन:

#include <array> 

typedef std::array<double, 2> Array; 

void foo(Array& a) __attribute__((optimize("unroll-loops"))); 

void foo(Array& a) 
{ 
    for (size_t ii = 0; ii < a.size(); ++ii) 
    a[ii] = 1.0; 
} 

यह काम करता है के रूप में -ffast-math बिना और भी जीसीसी 4.9 या 7 (पूर्व के साथ की उम्मीद -release)।

+1

क्या आपने किसी भी * डंप * झंडे का उपयोग किया था (जैसा कि @ टीसी द्वारा सुझाया गया है) यह देखने के लिए कि जीसीसी क्या सोच रही है और यह कॉल इनलाइन क्यों नहीं करती है? – Nawaz

+0

@ नवाज: नहीं। मुझे एहसास हुआ कि समस्या केवल उन डंप झंडे के बारे में समझने से पहले {जीसीसी 5/6, फास्ट-मैथ, अनोल-लूप्स} के संयोजन के साथ होती है। –

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