2016-09-06 13 views
5

जेएमएच के साथ खेलते समय मैं एक अजीब चीज में आया जो मैं समझा नहीं सकता।क्यों (एन मॉड कॉन्स) (कॉन्स मॉड एन) से तेज है?

@BenchmarkMode(Mode.SingleShotTime) 
@Measurement(iterations = 10, batchSize = Integer.MAX_VALUE) 
@Warmup(iterations = 5, batchSize = Integer.MAX_VALUE) 
@State(Scope.Thread) 
public class Tests { 
    private int value; 

    @Setup(Level.Iteration) 
    public void setUp() { 
     value = 1230; 
    } 

    @Benchmark 
    public boolean testConstModN() { 
     return 12345 % value == 0; 
    } 

    @Benchmark 
    public boolean testNModConst() { 
     return value % 12345 == 0; 
    } 
} 

परिणाम के नीचे

Benchmark     Mode Cnt Score Error Units 
Tests.testConstModN   ss 10 10.789 ± 0.305 s/op 
Tests.testNModConst   ss 10 7.550 ± 0.067 s/op 

मैं JDK 1.8.0_101, वीएम 25.101-B13, इंटेल (आर) कोर (टीएम) i7-4770 सीपीयू @ 3.40GHz (परिवार पर चल रहा हैं: 0x6, मॉडल: 0x3c, stepping: 0x3)

यदि मैं मान के बराबर कांस्ट सेट करता हूं या यदि मैं मान को 0xffffffff पर सेट करता हूं, तो कुछ भी नहीं बदलता है।

+0

एक समान% संख्या को चलाने के लिए प्रयास करें, जबकि वे बराबर हैं और मुझे परिणाम दिखाएं :) – Erik

+0

क्या होता है यदि आप 'मूल्य' 12345 पर सेट करते हैं और 1230 का उपयोग अपने निरंतर के रूप में करते हैं? – GriffeyDog

+0

मैंने प्रश्न में अतिरिक्त जानकारी जोड़ दी। इससे कोई फर्क नहीं पड़ता कि 'const' और' value' के मान क्या हैं। – Slonopotamus

उत्तर

7

CPU के DIV और MOD निर्देशों के पूर्णांक रिश्तेदार के आकार पर निर्भर बहुत महंगे हैं, 50 चक्र या उससे अधिक की लागत। जब आप एक चर विभाजक का उपयोग करते हैं, तो इन निर्देशों का उपयोग करना अपरिहार्य है। हालांकि, जब आप निरंतर विभाजक का उपयोग करते हैं, तो इसे MUL, ADD, और SHR जैसे बहुत सस्ता निर्देशों के संक्षिप्त अनुक्रम में संकलित किया जा सकता है।

Hacker's delight, chapter 10 इस समस्या को हल करने वाले कई एल्गोरिदम को शामिल करता है।

+0

विशेष रूप से निम्न शक्ति में कमी संभवतः खेल पर है: https://gmplib.org/~tege/divcnst-pldi94।पीडीएफ –

+0

अधिकतर एक मॉड्यूलर गुणात्मक उलटा (एक बड़े जादू स्थिरांक से गुणा करें, और ऊपरी आधे का उपयोग करें) –

+0

इसे जेआईटी कंपाइलर से उत्सर्जित वास्तविक मशीन कोड का निरीक्षण करके हल किया जा सकता है। मैंने इसे एक बार पहले किया था, शायद मुझे वह जवाब मिल सकता है ... –

1

तो मापांक केवल आंतरिक रूप से करने की जरूरत है इस जवाब खबरदार यह केवल अंतर्ज्ञान

यह % ऑपरेटर की प्रकृति की वजह से है

testNModConst() में 1230 12345 से भी कम है, उनके आकार की जाँच करें और है कि एहसास 12345 बड़ा है (एक ऑपरेशन)

testConstModN() 12345 में 1230 से अधिक है, इसलिए मॉड्यूलस को जवाब की गणना करने के लिए संचालन (घटाव) की एक श्रृंखला करना होगा।

यह लगातार

+0

अच्छी व्याख्या। परिणाम मूल सी या असेंबली पर्यावरण में देखने के लिए दिलचस्प होगा। – Beethoven

+1

अच्छा अनुमान। दुर्भाग्य से, यह एन और कॉन्स के मूल्यों पर निर्भर नहीं है। – Slonopotamus

+2

यह उत्तर वास्तव में यह नहीं दर्शाता है कि हार्डवेयर स्तर पर मॉड्यूलो ऑपरेशन कैसे किए जाते हैं। –

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