ऐसा करने का एक तरीका फ़ंक्शन पॉइंटर्स बनाना होगा जो सशर्त रूप से प्रीप्रोसेसर निर्देश के आधार पर विभिन्न कार्यों को इंगित करता है जो वांछित फीचर सेट का चयन करता है।

#if defined(__AVX512__)
    void (*func_ptr)() = _mm512_func;
#else
    void (*func_ptr)() = _mm256_func;
#endif

int main()
{
    func_ptr();
    return 0;
}

क्या ऐसा करने के बेहतर तरीके हैं? धन्यवाद।

0
Nanashi No Gombe 18 जून 2020, 00:10

1 उत्तर

सबसे बढ़िया उत्तर

यदि आप केवल संकलन समय पर AVX512 का पता लगा रहे हैं, तो आपको फ़ंक्शन पॉइंटर्स की आवश्यकता नहीं है।

सबसे आसान तरीका: एक ही फ़ंक्शन के लिए अलग-अलग नामों को बिल्कुल भी परिभाषित न करें, बस .cpp फ़ाइल में संकलित करने के लिए कौन सी परिभाषा चुनें, जहां आपके पास इसके कई संस्करण हैं। यह संकलन-समय प्रेषण को उस फ़ाइल से अलग रखता है जो फ़ंक्शन को परिभाषित करता है, आपके शेष कोड के लिए दृश्यमान नहीं है।

#ifdef __AVX512F__
void func(float *__restrict a, float *__restrict b) {
 ...  // AVX512 version here
}
#elif defined(__AVX2__) && defined(__FMA__)
void func(float *__restrict a, float *__restrict b) {          // same name
 ...  // AVX2 version here
}
#else
...       // SSE2 or scalar fallback
#endif

यद्यपि परीक्षण के लिए आप शायद इसके सभी संस्करणों को बनाने में सक्षम होना चाहते हैं और उन्हें एक-दूसरे के खिलाफ परीक्षण + बेंचमार्क करना चाहते हैं, इसलिए आप #define func _mm512_func का उपयोग करने या उस फ़ाइल के अंदर कुछ प्रीप्रोसेसर चाल का उपयोग करने पर विचार कर सकते हैं। हो सकता है कि किसी अन्य उत्तर के लिए इसके लिए एक बेहतर विचार होगा।


मैंने सोचा था कि सी ++ समुदाय में मैक्रोज़ पर फ़ंक्शन पॉइंटर्स को प्राथमिकता दी गई थी। लेकिन यह वही काम करता है

हो सकता है कि यदि फ़ंक्शन बिंदु void (*static const func_ptr)() है तो आप इसे इनलाइन/अनुकूलित होने पर भरोसा कर सकते हैं। यदि आपको इसकी आवश्यकता नहीं है तो आप वास्तव में प्रेषण के लिए अतिरिक्त ओवरहेड नहीं जोड़ना चाहते हैं (उदाहरण के लिए रनटाइम CPU पहचान के लिए, cpuid चलाने वाले init फ़ंक्शन में फ़ंक्शन पॉइंटर्स सेट करना)

3
Peter Cordes 18 जून 2020, 01:14