7

मुझे जावाकार्ड में 16-बाइट सरणी के जितनी जल्दी संभव बाएं बिट शिफ्ट को लागू करने की आवश्यकता है।बाइट सरणी की फास्ट बिट शिफ्ट - सीएमएसी उपकुंजी

private static final void rotateLeft(final byte[] output, final byte[] input) { 
     short carry = 0; 
     short i = (short) 16; 
     do { 
      --i; 
      carry = (short)((input[i] << 1) | carry); 
      output[i] = (byte)carry; 
      carry = (short)((carry >> 8) & 1); 
     } while (i > 0); 
} 

कोई भी विचार कैसे performace सुधार करने के लिए:

मैं इस कोड की कोशिश की? मैं कुछ Util.getShort(...) और Util.setShort(...) जादू के बारे में सोच रहा था, लेकिन मैंने ऊपर कार्यान्वयन के बाद इसे तेजी से काम करने में कामयाब नहीं किया।

यह सीएमएसी उपकुंजियों की गणना का एक हिस्सा है और दुर्भाग्य से यह अक्सर किया जाता है। यदि आप सीएमएसी उपकुंजी (दोनों लूप में उपकुंजी या उस तरह कुछ) की गणना करने के लिए कुछ तेज़ तरीका जानते हैं, तो कृपया मुझे बताएं।

+0

मैं जावाकार्ड को इकट्ठा करता हूं? यदि ऐसा है तो मैं अनुशंसा करता हूं कि आप जेनरेट किए गए बाइट-कोड पर नज़र डालें और उपलब्ध निर्देश सेट के साथ अनुकूलित करें। उदाहरण के लिए मुझे संदेह है कि शर्ट शॉर्ट्स के लिए बेहतर हो सकता है, और लूप अनोलिंग आपको कुछ चक्र प्राप्त कर सकता है। इसके अलावा मुझे संदेह है कि आप एक विस्तारित-सटीक अंकगणितीय ऑपरेशन से अधिक करने जा रहे हैं, इसलिए संभवतया तेज़ प्रसंस्करण के लिए व्यापक पूर्णांक पर स्विच करना और अंत में 8-बिट सरणी को वापस परिवर्तित करना बुद्धिमानी है। – doynax

+0

@doynax जावाकार्ड में 'int' या' long' नहीं है ... 'बाइट' और 'छोटा' आपके पास है। – vojta

+0

इसके बारे में क्षमा करें, काम करने के लिए विशेष रूप से अपंग वातावरण की तरह लगता है। मेरा बिंदु अभी भी खड़ा है, जेनरेट किए गए बाइट कोड पर नजर रखें ताकि यह सुनिश्चित किया जा सके कि कंपाइलर इंटरमीडिएट शॉर्ट-ऑफ-इंट-एंड-न-वास्तव में परिणामों पर अनावश्यक 'i2s' निर्देश उत्पन्न करने का निर्णय नहीं लेता है। – doynax

उत्तर

3

जब गति की बात आती है, ज्ञात लंबाई, हार्ड-कोडेड संस्करण सबसे तेज़ (लेकिन बदसूरत) होता है। यदि आपको एक से अधिक बिट स्थानांतरित करने की आवश्यकता है, तो तदनुसार कोड अपडेट करना सुनिश्चित करें।

output[0] = (byte)((byte)(input[0] << 1) | (byte)((input[1] >> 7) & 1)); 
output[1] = (byte)((byte)(input[1] << 1) | (byte)((input[2] >> 7) & 1)); 
output[2] = (byte)((byte)(input[2] << 1) | (byte)((input[3] >> 7) & 1)); 
output[3] = (byte)((byte)(input[3] << 1) | (byte)((input[4] >> 7) & 1)); 
output[4] = (byte)((byte)(input[4] << 1) | (byte)((input[5] >> 7) & 1)); 
output[5] = (byte)((byte)(input[5] << 1) | (byte)((input[6] >> 7) & 1)); 
output[6] = (byte)((byte)(input[6] << 1) | (byte)((input[7] >> 7) & 1)); 
output[7] = (byte)((byte)(input[7] << 1) | (byte)((input[8] >> 7) & 1)); 
output[8] = (byte)((byte)(input[8] << 1) | (byte)((input[9] >> 7) & 1)); 
output[9] = (byte)((byte)(input[9] << 1) | (byte)((input[10] >> 7) & 1)); 
output[10] = (byte)((byte)(input[10] << 1) | (byte)((input[11] >> 7) & 1)); 
output[11] = (byte)((byte)(input[11] << 1) | (byte)((input[12] >> 7) & 1)); 
output[12] = (byte)((byte)(input[12] << 1) | (byte)((input[13] >> 7) & 1)); 
output[13] = (byte)((byte)(input[13] << 1) | (byte)((input[14] >> 7) & 1)); 
output[14] = (byte)((byte)(input[14] << 1) | (byte)((input[15] >> 7) & 1)); 
output[15] = (byte)(input[15] << 1); 

और रैम बाइट सरणी का उपयोग करें!

+0

धन्यवाद! हालांकि, मुझे लगता है कि आप बहुत अधिक कास्टिंग का उपयोग करते हैं ...आप केवल अंतिम परिणाम निकाल सकते हैं और जितना संभव हो सके int ... – vojta

+0

बस ध्यान दें: आश्चर्यजनक रूप से, लूप अनोलिंग सामान्य रूप से सबसे तेज़ नहीं है, भले ही निम्न स्तर के असेंबलर निर्देशों की बात आती है। –

+0

@ एंटन सैमसनोव यह कैसे संभव है? – vojta

2

यह उसी कुंजी का उपयोग करके बार-बार हस्ताक्षर करते समय सीएमएसी उपकुंजियों को कैश करने में मदद कर सकता है (यानी एक ही DESFire EV1 सत्र कुंजी)। उपकुंजी हमेशा दी गई कुंजी के लिए समान होती हैं।

मुझे लगता है कि डेविड का जवाब तब भी तेज हो सकता है जब इनपुट इनपुट सरणी के उसी ऑफसेट से दो बार पढ़ने वाले मानों को कैश करने के लिए दो स्थानीय चर का उपयोग किया जाता है (जेसीओपी पर मेरे अवलोकनों से, सरणी का उपयोग क्षणिक सरणी के लिए भी महंगा है) ।

संपादित करें: मैं निम्नलिखित कार्यान्वयन जो 4 बिट सही (समर्थन यह भी तेजी से किया जाएगा कार्ड के लिए 32-बिट पूर्णांक संस्करण) कम का उपयोग कर पारी करता है प्रदान कर सकते हैं:

short pom=0; // X000 to be stored next 
short pom2; // loaded value 
short pom3; // 0XXX to be stored next 
short curOffset=PARAMS_TRACK2_OFFSET; 
while(curOffset<16) { 
    pom2=Util.getShort(mem_PARAMS, curOffset); 
    pom3=(short)(pom2>>>4); 
    curOffset=Util.setShort(mem_RAM, curOffset, (short)(pom|pom3)); 
    pom=(short)(pom2<<12); 
} 

सावधान रहें, इस कोड को एक ही मान लिया गया है ऑफसेट स्रोत और गंतव्य में।

आप इस लूप को अनलॉक कर सकते हैं और वांछित होने पर निरंतर पैरामीटर का उपयोग कर सकते हैं।

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