ඉන්ටෙල් ප්රොසෙසර (සහ තවත් සමහරක්) ගබඩා කිරීම සඳහා කුඩා එන්ඩියන් ආකෘතිය භාවිතා කරයි.
යමෙකුට බයිට් ප්රතිලෝම අනුපිළිවෙලට ගබඩා කිරීමට අවශ්ය වන්නේ මන්දැයි මම නිතරම කල්පනා කරමි. විශාල එන්ඩියන් ආකෘතියට වඩා මෙම ආකෘතියට වාසි තිබේද?
ඉන්ටෙල් ප්රොසෙසර (සහ තවත් සමහරක්) ගබඩා කිරීම සඳහා කුඩා එන්ඩියන් ආකෘතිය භාවිතා කරයි.
යමෙකුට බයිට් ප්රතිලෝම අනුපිළිවෙලට ගබඩා කිරීමට අවශ්ය වන්නේ මන්දැයි මම නිතරම කල්පනා කරමි. විශාල එන්ඩියන් ආකෘතියට වඩා මෙම ආකෘතියට වාසි තිබේද?
Answers:
දෙයාකාරයෙන්ම තර්ක තිබේ, නමුත් එක් කරුණක් නම්, කුඩා එන්ඩියන් පද්ධතියක, මතකයේ දී ඇති අගයක ලිපිනය 32, 16 හෝ 8 බිට් පළල ලෙස ගත් විට සමාන වේ.
වෙනත් වචන වලින් කිවහොත්, ඔබට මතකයේ බයිට් දෙකක අගයක් තිබේ නම්:
0x00f0 16
0x00f1 0
එම '16' බිටු 16 ක අගයක් ලෙස (බොහෝ බිට් 32 පද්ධතිවල සී 'කෙටි') හෝ 8-බිට් අගයක් ලෙස (සාමාන්යයෙන් සී 'චාර්') වෙනස් කරන්නේ ඔබ භාවිතා කරන උපදෙස් පමණි - ඔබ ලබා ගන්නා ලිපිනය නොවේ සිට.
විශාල-එන්ඩියන් පද්ධතියක, ඉහත සඳහන් පරිදි:
0x00f0 0
0x00f1 16
ඔබට දර්ශකය වැඩි කිරීමට අවශ්ය වන අතර පසුව නව අගය මත පටු ලබා ගැනීමේ ක්රියාවලිය සිදු කළ යුතුය.
ඉතින්, කෙටියෙන් කිවහොත්, 'කුඩා එන්ඩියන් පද්ධතිවල, කැස්ට් යනු කිසිදු විකල්පයක් නොවේ.'
යමෙකුට බයිට් ප්රතිලෝම අනුපිළිවෙලට ගබඩා කිරීමට අවශ්ය වන්නේ මන්දැයි මම නිතරම කල්පනා කරමි.
බිග්-එන්ඩියන් සහ කුඩා එන්ඩියන් යනු මිනිස් දෘෂ්ටිකෝණයකින් “සාමාන්ය අනුපිළිවෙල” සහ “ප්රතිලෝම අනුපිළිවෙල” පමණි, එවිට මේ සියල්ල සත්ය නම් පමණි ...
ඒවා සියල්ලම CPU එකකට කිසිසේත්ම වැදගත් නොවන මානව සම්මුතීන් වේ. ඔබ # 1 සහ # 2 රඳවා තබා # 3 පෙරළා දැමුවහොත්, අරාබි හෝ හෙබ්රෙව් භාෂාව කියවන අයට දකුණේ සිට වමට ලියා ඇති කුඩා එන්ඩියන් “පරිපූර්ණ ස්වාභාවික” යැයි පෙනේ.
බිග්-එන්ඩියන් අස්වාභාවික යැයි පෙනෙන වෙනත් මානව සම්මුතීන් ඇත, වැනි ...
මම වැඩිපුරම 68K සහ PowerPC ක්රමලේඛනය කරන විට, බිග්-එන්ඩියන් "හරි" සහ කුඩා එන්ඩියන් "වැරදි" ලෙස මම සලකමි. නමුත් මම වැඩි ARM සහ Intel වැඩ කරන බැවින්, මම කුඩා එන්ඩියන් වලට පුරුදු වී සිටිමි. එය ඇත්තෙන්ම කමක් නැත.
හරි, මෙන්න මට එය පැහැදිලි කළ පරිදි හේතුව: එකතු කිරීම හා අඩු කිරීම
ඔබ බහු-බයිට් අංක එකතු කරන විට හෝ අඩු කරන විට, ඔබ අවම වශයෙන් සැලකිය යුතු බයිට් වලින් ආරම්භ කළ යුතුය. උදාහරණයක් ලෙස ඔබ බිට් 16 අංක දෙකක් එකතු කරන්නේ නම්, අවම වශයෙන් සැලකිය යුතු බයිට් සිට වඩාත්ම වැදගත් බයිට් වෙත රැගෙන යා හැකිය, එබැවින් රැගෙන යාමක් තිබේදැයි බැලීමට ඔබට අවම වශයෙන් වැදගත් බයිට් වලින් ආරම්භ කළ යුතුය. දිගුකාලීන එකතු කිරීමක් සිදු කරන විට ඔබ නිවැරදි ඉලක්කම් සමඟ ආරම්භ කිරීමට එකම හේතුව මෙයයි. ඔබට වමේ සිට ආරම්භ කළ නොහැක.
මතකයෙන් අනුපිළිවෙලින් බයිට් ලබා ගන්නා 8-බිට් පද්ධතියක් සලකා බලන්න. පළමුවෙන්ම අඩුම වැදගත් බයිට් එකක් ලබා ගන්නේ නම් , එය එකතු කිරීම ආරම්භ කළ හැකි අතර වඩාත්ම වැදගත් බයිට් මතකයෙන් ලබා ගනී. මෙම සමාන්තරකරණය නිසා පද්ධතිය වැනි කුඩා එන්ඩියන් වල කාර්ය සාධනය වඩා හොඳ වන්නේ එබැවිනි. බයිට් දෙකම මතකයෙන් ලබා ගන්නා තෙක් බලා සිටීමට හෝ ප්රතිලෝම අනුපිළිවෙලට ඒවා ලබා ගැනීමට සිදුවුවහොත් එය වැඩි කාලයක් ගතවනු ඇත.
මෙය පැරණි 8-බිට් පද්ධති මත වේ. නවීන CPU එකක බයිට් අනුපිළිවෙලෙහි යම් වෙනසක් සිදු වන බවට මට සැකයක් ඇති අතර අපි එන්ඩියන් භාවිතා කරන්නේ historical තිහාසික හේතූන් සඳහා පමණි.
බිට් ප්රොසෙසර 8 ක් සමඟ එය නිසැකවම වඩා කාර්යක්ෂම වූ අතර, ඔබට විවිධ කේත අවශ්ය නොවී සහ අමතර අගයන් ආරක්ෂා කිරීමට අවශ්ය නොවී 8 හෝ 16bit මෙහෙයුමක් කළ හැකිය.
ඔබ වරකට බයිට් එකක් ගනුදෙනු කරන්නේ නම් සමහර එකතු කිරීමේ මෙහෙයුම් සඳහා එය තවමත් හොඳය.
බිග්-එන්ඩියන් වඩාත් ස්වාභාවික බවට කිසිදු හේතුවක් නැත - ඉංග්රීසියෙන් ඔබ දහතුනක් (කුඩා එන්ඩියන්) සහ විසිතුනක් (ලොකු එන්ඩියන්) භාවිතා කරයි
0x12345678
ගබඩා කර 78 56 34 12
ඇති අතර එය BE පද්ධතියක් මත ගබඩා කර ඇත 12 34 56 78
(බයිට් 0 වම් පසින්, බයිට් 3 දකුණේ). සංඛ්යාව කොතරම් විශාලද යන්න සැලකිල්ලට ගන්න (බිටු අනුව), වැඩි හුවමාරුවක් අවශ්ය වේ; වචනයකට එක් හුවමාරුවක් අවශ්ය වේ; DWORD, පාස් දෙකක් (මුළු හුවමාරු තුනක්); QWORD පාස් තුනක් (මුළු 7 ක්), සහ එසේ ය. එනම්, (bits/8)-1
හුවමාරුව. තවත් විකල්පයක් නම් ඒවා ඉදිරියට සහ පසුපසට කියවීමයි (එක් එක් බයිට් ඉදිරියට කියවීම, නමුත් මුළු # පසුපසට පරිලෝකනය කිරීම).
0x12345678
ගබඩා කර 87 65 43 21
ඇත්තේ යමෙකු එය ලිවීමට තෝරා ගන්නා ආකාරය අනුව ය. යමෙකු අත්තනෝමතික ලෙස යමක් ලියන ආකාරය (කියවන්න: සන්දර්භය මත රඳා පවතී).
ජපන් දින සමුළුව "බිග් එන්ඩියන්" - yyyy / mm / dd. ඇල්ගොරිතම වර්ග කිරීම සඳහා මෙය පහසුය, එමඟින් සරල නූල් භාවිතා කළ හැකිය - සුපුරුදු පළමු අක්ෂරය සමඟ සැසඳීම-වඩාත්ම වැදගත් රීතිය.
වඩාත්ම වැදගත්-ක්ෂේත්ර-පළමු වාර්තාවක ගබඩා කර ඇති විශාල-එන්ඩියන් අංක සඳහා සමාන දෙයක් අදාළ වේ. ක්ෂේත්ර තුළ ඇති බයිට් වල වැදගත් අනුපිළිවෙල, වාර්තාව තුළ ඇති ක්ෂේත්රවල වැදගත්කමට ගැලපේ, එබැවින් ඔබට memcmp
වාර්තා සංසන්දනය කිරීමට භාවිතා කළ හැකිය, ඔබ දිගු වචන දෙකක්, වචන හතරක් හෝ වෙනම බයිට් අටක් සංසන්දනය කරන්නේද යන්න ගැන එතරම් තැකීමක් නොකරයි.
ක්ෂේත්රවල වැදගත්කමේ අනුපිළිවෙල පෙරළන්න, ඔබට එකම වාසියක් ලැබෙනු ඇත, නමුත් විශාල-එන්ඩියන් වලට වඩා කුඩා-එන්ඩියන් සංඛ්යා සඳහා.
ඇත්ත වශයෙන්ම මෙය ප්රායෝගික වැදගත්කමක් නැති තරම්ය. ඔබේ වේදිකාව විශාල-එන්ඩියන් හෝ කුඩා-එන්ඩියන් වේවා, ඔබට ඇත්ත වශයෙන්ම අවශ්ය නම් මෙම උපක්රමය සූරාකෑමට වාර්තා ක්ෂේත්රයක් ඇණවුම් කළ හැකිය. ඔබට අතේ ගෙන යා හැකි කේතයක් ලිවීමට අවශ්ය නම් එය වේදනාවක් පමණි .
මම සම්භාව්ය අභියාචනයට සබැඳියක් ද ඇතුළත් කළ හැකිය ...
http://tools.ietf.org/rfcmarkup?url=ftp://ftp.rfc-editor.org/in-notes/ien/ien137.txt
සංස්කරණය කරන්න
අමතර සිතුවිල්ලක්. මම වරක් විශාල සංඛ්යා පුස්තකාලයක් ලියා (මට හැකි දැයි බැලීමට), ඒ සඳහා, බිටු 32 ක් පළල කුට්ටි කුඩා-එන්ඩියන් අනුපිළිවෙලෙහි ගබඩා කර ඇත, වේදිකාව එම කුට්ටි වල බිටු ඇණවුම් කරන්නේ කෙසේද යන්න නොසලකා. හේතු ...
බොහෝ ඇල්ගොරිතම ස්වාභාවිකවම අවම වශයෙන් සැලකිය යුතු අවසානයකින් වැඩ කිරීමට පටන් ගන්නා අතර එම අන්තයන් ගැලපීමට අවශ්ය වේ. උදාහරණයක් ලෙස ඊට අමතරව, වැඩි වැඩියෙන් වැදගත් ඉලක්කම් වෙත ප්රක්ෂේපණය කරයි, එබැවින් අවම වශයෙන් සැලකිය යුතු අවසානයකින් ආරම්භ කිරීම අර්ථවත් කරයි.
වටිනාකමක් වැඩීම හෝ හැකිලීම යන්නෙන් අදහස් කරන්නේ අවසානයේ කුට්ටි එකතු කිරීම / ඉවත් කිරීමයි - කුට්ටි ඉහළට / පහළට මාරු කිරීම අවශ්ය නොවේ. මතක නැවත ස්ථානගත කිරීම හේතුවෙන් පිටපත් කිරීම තවමත් අවශ්ය විය හැකි නමුත් බොහෝ විට එසේ නොවේ.
මෙය සකසනයන්ට පැහැදිලිව අදාළ නොවේ, ඇත්ත වශයෙන්ම - දෘඩාංග විශාල-පූර්ණ සංඛ්යා ආධාරයෙන් CPU නිපදවන තුරු, එය තනිකරම පුස්තකාල දෙයක්.
මෙය සිදු කළ හැක්කේ මන්දැයි වෙන කිසිවෙකු පිළිතුරු දී නැත, ප්රතිවිපාක පිළිබඳ බොහෝ දේ.
දී ඇති ඔරලෝසු චක්රයක් තුළ මතකයෙන් තනි බයිට් එකක් පැටවිය හැකි බිට් 8 ප්රොසෙසරයක් සලකා බලන්න.
දැන්, ඔබට බිට් 16 ක අගයක් පැටවීමට අවශ්ය නම්, ඔබ සතුව ඇති එකම සහ එකම බිට් 16 ලේඛනයට (එනම්) - එනම් ක්රමලේඛ කවුන්ටරය, එය කිරීමට සරල ක්රමයක් නම්:
ප්රති come ලය: ඔබ කවදා හෝ ලබා ගැනීමේ ස්ථානය වැඩි කරන්නේ නම්, ඔබ කවදා හෝ පටවා ඇත්තේ ඔබගේ අඩු ලේඛනයේ පුළුල් ලේඛනයේ පමණි, ඔබට අවශ්ය වන්නේ වමට මාරුවීමට පමණි. (ඇත්ත වශයෙන්ම, දකුණට මාරුවීම වෙනත් මෙහෙයුම් සඳහා උපකාරී වේ, එබැවින් මෙය පැත්තක දර්ශනයකි.)
මෙහි ප්රති consequ ලයක් ලෙස බිට් 16 (ද්විත්ව බයිට්) දේවල් බොහෝ පිළිවෙලට ගබඩා කර ඇත. එනම්, කුඩා ලිපිනයට වඩාත්ම වැදගත් බයිට් ඇත - එතරම් විශාල එන්ඩියන්.
ඔබ ඒ වෙනුවට කුඩා එන්ඩියන් භාවිතයෙන් පැටවීමට උත්සාහ කළේ නම්, ඔබට ඔබේ පුළුල් ලේඛනයේ පහළ කොටසට බයිට් එකක් පැටවීමට අවශ්ය වනු ඇත, ඉන්පසු ඊළඟ බයිටය වේදිකාගත වන ප්රදේශයකට පටවා එය මාරු කර ඔබේ පුළුල් ලේඛනයේ ඉහළට පොප් කරන්න. . නැතහොත් ඉහළ හෝ පහළ බයිට් වලට තෝරා බේරා ගැනීමට හැකි වන පරිදි වඩාත් සංකීර්ණ ගේට්ටු සැකැස්මක් භාවිතා කරන්න.
කුඩා එන්ඩියන් වෙත යාමට උත්සාහ කිරීමේ ප්රති result ලය නම් ඔබට තවත් සිලිකන් (ස්විච සහ ගේට්ටු) හෝ තවත් මෙහෙයුම් අවශ්ය වේ.
වෙනත් වචන වලින් කිවහොත්, පැරණි දිනවල නැවත මුදල් ලබා ගැනීම සම්බන්ධයෙන් ගත් කල, ඔබට බොහෝ කාර්ය සාධනය සහ කුඩාම සිලිකන් ප්රදේශය සඳහා වැඩි වේගයක් ලැබුණි.
මෙම දින තුළ, මෙම සලකා බැලීම් හා එච්චරමයි අනදාල, නමුත් නල තෘප්තියට වැනි දේවල් විය හැක තවමත් ලොකු ගනුදෙනුවක් ටිකක් විය.
S / w ලිවීමේදී, කුඩා එන්ඩියන් ලිපින භාවිතා කරන විට ජීවිතය නිතරම පහසු වේ.
(ඒ මහා endian සකසන බිටු-in-බයිට් අනුව බයිට ඇනවුම් සහ කුඩා endian අනුව විශාල endian විය හැක. නමුත් සමහර දත්ත සැකසුම් ඒකක අමුතු හා බයිට ඇනවුම් කිරීම මෙන්ම විශාල endian ටිකක් ඇනවුම් කිරීම භාවිතා කරනු ඇත. මෙම ජීවිතය කරයි ඉතා මතක සිතියම්ගත කරන ලද පර්යන්ත එකතු කරන h / w නිර්මාණකරුට සිත්ගන්නාසුළු නමුත් එය ක්රමලේඛකයාට වෙනත් ප්රති ence ලයක් නොවේ.)
ජිම්වයිස් හොඳ අදහසක් ඉදිරිපත් කළේය. තවත් ගැටලුවක් තිබේ, කුඩා එන්ඩියන් භාෂාවෙන් ඔබට පහත සඳහන් දෑ කළ හැකිය:
byte data[4];
int num=0;
for(i=0;i<4;i++)
num += data[i]<<i*8;
OR
num = *(int*)&data; //is interpreted as
mov dword data, num ;or something similar it has been some time
මතකයේ හුවමාරු වූ ස්ථානවල පැහැදිලිවම අවාසි වලින් බලපෑමට ලක් නොවන ක්රමලේඛකයින් සඳහා වඩාත් forward ජුව ඉදිරියට. මම පෞද්ගලිකව ලොකු එන්ඩියන් ස්වාභාවික දේට ප්රතිලෝමව සිටින බව සොයා ගතිමි :). 12 ගබඩා කර 21 ලෙස ලිවිය යුතුය :)
for(i=0; i<4; i++) { num += data[i] << (24 - i * 8); }
අනුරූප වේ move.l data, num
.
යමෙකුට බයිට් ප්රතිලෝම අනුපිළිවෙලට ගබඩා කිරීමට අවශ්ය වන්නේ මන්දැයි මම නිතරම කල්පනා කරමි
දශම අංකය විශාල එන්ඩියන් ලෙස ලියා ඇත. එය ඔබ ඉංග්රීසියෙන් ලියන ආකාරය ද ඔබ ආරම්භ කරන්නේ වඩාත්ම වැදගත් ඉලක්කම් වලින් වන අතර ඊළඟට වඩාත්ම වැදගත් සිට අවම වශයෙන් වැදගත් වේ. උදා
1234
යනු දහසක්, දෙසිය තිස් හතරකි.
විශාල එන්ඩියන් සමහර විට ස්වාභාවික අනුපිළිවෙල ලෙස හැඳින්වේ.
කුඩා එන්ඩියන් භාෂාවෙන් මෙම සංඛ්යාව එක, විසි, තුන්සිය හාරදහසක් වනු ඇත.
කෙසේ වෙතත්, ඔබ එකතු කිරීම හෝ අඩු කිරීම වැනි අංක ගණිතය සිදු කරන විට, ඔබ අවසානය සමඟ ආරම්භ කරයි.
1234
+ 0567
====
ඔබ 4 සහ 7 සමඟ ආරම්භ කර, අවම ඉලක්කම් ලියන්න සහ රැගෙන යාම මතක තබා ගන්න. ඉන්පසු ඔබ 3 සහ 6 යනාදිය එකතු කරයි. එකතු කිරීම, අඩු කිරීම හෝ සංසන්දනය කිරීම සඳහා, මතකය පිළිවෙලට කියවීමට ඔබට දැනටමත් තර්කනයක් තිබේ නම්, සංඛ්යා ආපසු හරවනු ලැබේ නම් එය ක්රියාත්මක කිරීම පහසුය.
මේ ආකාරයට විශාල එන්ඩියන් සඳහා සහය දැක්වීමට, ඔබට මතකය ප්රතිලෝමව කියවීමට තර්කනය අවශ්ය වේ, නැතහොත් ඔබට RISC ක්රියාවලියක් ඇති අතර එය ක්රියාත්මක වන්නේ රෙජිස්ටරවල පමණි. ;)
Intel x86 / Amd x64 නිර්මාණය ගොඩක් is තිහාසිකයි.
බිග්-එන්ඩියන් සමහර මෙහෙයුම් සඳහා ප්රයෝජනවත් වේ (මතකයට සමාන අෂ්ටක දිග උල්පත් වල "බිග්නම්" සංසන්දනය). අනෙක් අයට කුඩා-එන්ඩියන් (සමහර විට "බිග්නම්" දෙකක් එකතු කිරීම). අවසානයේදී, එය රඳා පවතින්නේ CPU දෘඩාංග සඳහා සකසා ඇති දේ මතය, එය සාමාන්යයෙන් එකක් හෝ වෙනත් ය (සමහර MIPS චිප්ස්, IIRC, ඇරඹුම් මත මාරු කළ හැකි LE හෝ BE විය).
විචල්ය දිග සමඟ ගබඩා කිරීම හා මාරු කිරීම පමණක් සිදු වන නමුත් බහු අගයන් සහිත අංක ගණිතයක් නොමැති විට LE සාමාන්යයෙන් ලිවීමට පහසු වන අතර BE කියවීමට පහසු වේ.
නිශ්චිත උදාහරණයක් ලෙස අපි අන්තර්-නූල් පරිවර්තනයක් (සහ පසුපසට) ගනිමු.
int val_int = 841;
char val_str[] = "841";
Int එක නූල් බවට පරිවර්තනය කළ විට, වඩාත්ම වැදගත් ඉලක්කම් වලට වඩා අවම සැලකිය යුතු ඉලක්කම් නිස්සාරණය කිරීම පහසුය. ඒ සියල්ල සරල අන්ත තත්වයකින් සරල ලූපයකින් කළ හැකිය.
val_int = 841;
// Make sure that val_str is large enough.
i = 0;
do // Write at least one digit to care for val_int == 0
{
// Constants, can be optimized by compiler.
val_str[i] = '0' + val_int % 10;
val_int /= 10;
i++;
}
while (val_int != 0);
val_str[i] = '\0';
// val_str is now in LE "148"
// i is the length of the result without termination, can be used to reverse it
දැන් BE අනුපිළිවෙලින් එයම උත්සාහ කරන්න. සාමාන්යයෙන් ඔබට නිශ්චිත සංඛ්යාවක් සඳහා විශාලතම බලය 10 ක් ඇති තවත් බෙදුම්කරුවෙකු අවශ්ය වේ (මෙහි 100). ඔබ මුලින්ම මෙය සොයා ගත යුතුයි. තවත් බොහෝ දේ කිරීමට තිබේ.
ප්රතිලෝම ලිවීමේ මෙහෙයුම ලෙස එය සිදු කළ විට, ඉන්ට් පරිවර්තනයේ නූල BE හි කිරීමට පහසුය. වඩාත්ම වැදගත් ඉලක්කම් අන්තිමට ලියන්න, එබැවින් එය පළමුව කියවිය යුතුය.
val_int = 0;
length = strlen(val_str);
for (i = 0; i < length; i++)
{
// Again a simple constant that can be optimized.
val_int = 10*val_int + (val_str[i] - '0');
}
දැන් LE අනුපිළිවෙලින් එය කරන්න. නැවතත්, ඔබට 1 න් ආරම්භ වන අතිරේක සාධකයක් අවශ්ය වන අතර එක් එක් ඉලක්කම් සඳහා 10 කින් ගුණ කළ යුතුය.
මේ අනුව මම සාමාන්යයෙන් ගබඩා කිරීම සඳහා BE භාවිතා කිරීමට කැමැත්තෙමි, මන්ද අගයක් හරියටම එක් වරක් ලියා ඇති නමුත් අවම වශයෙන් එක් වරක් හෝ බොහෝ විට කියවන්න. එහි සරල ව්යුහය සඳහා, මම සාමාන්යයෙන් LE වෙත පරිවර්තනය වීමටත්, ප්රති second ලය ආපසු හැරවීමටත්, එය දෙවන වරටත් අගය ලිවුවද.
BE ගබඩා කිරීම සඳහා තවත් උදාහරණයක් වනුයේ UTF-8 කේතන ක්රමය සහ තවත් බොහෝ දේ ය.