ඔබ ශාඛා අනාවැකි අසාර්ථක වීමේ ගොදුරක් .
ශාඛා පුරෝකථනය යනු කුමක්ද?
දුම්රිය මංසන්ධියක් සලකා බලන්න:
රූපය මෙකනිස්මෝ, විකිමීඩියා කොමන්ස් හරහා. යටතේ භාවිතා CC-BY-SA 3.0 බලපත්රය.
දැන් තර්කය සඳහා, මෙය 1800 ගණන්වල - දිගු දුර හෝ ගුවන් විදුලි සන්නිවේදනයට පෙර යැයි සිතමු.
ඔබ හන්දියක ක්රියාකරු වන අතර දුම්රියක් පැමිණෙන බව ඔබට ඇසේ. එය යා යුත්තේ කුමන මාර්ගයටදැයි ඔබට අදහසක් නැත. ඔබ දුම්රිය නතර කරන්නේ රියදුරුට අවශ්ය දිශාව කුමක්දැයි විමසීමටයි. ඉන්පසු ඔබ ස්විචය සුදුසු පරිදි සකසා ගන්න.
දුම්රිය බරින් යුක්ත වන අතර විශාල අවස්ථිති බවක් ඇත. එබැවින් ඔවුන් ආරම්භ කිරීමට හා මන්දගාමී වීමට සදහටම ගත වේ.
මීට වඩා හොඳ ක්රමයක් තිබේද? ඔබ සිතන්නේ දුම්රිය යන්නේ කුමන දිශාවටද කියා!
- ඔබ නිවැරදිව අනුමාන කළහොත්, එය දිගටම පවතී.
- ඔබ වැරදියට අනුමාන කළහොත්, කපිතාන්වරයා නවත්වනු ඇත, උපස්ථ වේ, සහ ස්විචය පෙරළීමට කෑගසනු ඇත. එවිට එය අනෙක් මාර්ගය නැවත ආරම්භ කළ හැකිය.
ඔබ සෑම විටම නිවැරදිව අනුමාන කරන්නේ නම් , දුම්රිය කිසි විටෙකත් නැවැත්විය යුතු නැත.
ඔබ බොහෝ විට වැරදි යැයි අනුමාන කරන්නේ නම් , දුම්රිය නැවැත්වීමට, උපස්ථ කිරීමට සහ නැවත ආරම්භ කිරීමට බොහෝ කාලයක් ගත කරනු ඇත.
If-statement එකක් සලකා බලන්න: ප්රොසෙසර් මට්ටමින් එය ශාඛා උපදෙස් වේ:
ඔබ ප්රොසෙසරයක් වන අතර ඔබට ශාඛාවක් පෙනේ. එය යන්නේ කුමන දිශාවටදැයි ඔබට අදහසක් නැත. ඔයා මොකද කරන්නේ? ඔබ ක්රියාත්මක කිරීම නවතා පෙර උපදෙස් සම්පූර්ණ වන තෙක් රැඳී සිටින්න. එවිට ඔබ නිවැරදි මාවතේ ඉදිරියට යන්න.
නවීන සකසනයන් සංකීර්ණ වන අතර දිගු නල මාර්ග ඇත. එබැවින් ඔවුන් "උණුසුම් වීමට" සහ "වේගය අඩු කිරීමට" සදහටම ගනී.
මීට වඩා හොඳ ක්රමයක් තිබේද? ශාඛාව යන්නේ කුමන දිශාවටදැයි ඔබ අනුමාන කරයි!
- ඔබ නිවැරදිව අනුමාන කළහොත්, ඔබ දිගටම ක්රියාත්මක කරයි.
- ඔබ වැරදි යැයි අනුමාන කළහොත්, ඔබට නල මාර්ගය ගලවා නැවත ශාඛාවට පෙරළීමට අවශ්යය. එවිට ඔබට අනෙක් මාර්ගය නැවත ආරම්භ කළ හැකිය.
ඔබ සෑම විටම නිවැරදිව අනුමාන කරන්නේ නම් , ක්රියාත්මක කිරීම කිසි විටෙකත් නතර කළ යුතු නොවේ.
ඔබ බොහෝ විට වැරදි යැයි අනුමාන කරන්නේ නම් , ඔබ බොහෝ වේලාවක් ඇණහිටීම, පෙරළීම සහ නැවත ආරම්භ කිරීම සඳහා වැය කරයි.
මෙය ශාඛා පුරෝකථනයයි. දුම්රියට ධජයකින් දිශාව සං signal ා කළ හැකි බැවින් එය හොඳම ප්රතිසමයක් නොවන බව මම පිළිගනිමි. නමුත් පරිගණක වලදී, අවසාන මොහොත දක්වා ශාඛාවක් යන්නේ කුමන දිශාවටද යන්න ප්රොසෙසරය නොදනී.
ඉතින්, දුම්රිය උපස්ථ වී අනෙක් මාර්ගයෙන් බැස යා යුතු වාර ගණන අවම කිරීමට ඔබ උපායමාර්ගිකව අනුමාන කරන්නේ කෙසේද? ඔබ අතීත ඉතිහාසය දෙස බලයි! දුම්රිය 99% ක් වමට ගියහොත් ඔබ අනුමාන කරන්නේ වමට ය. එය විකල්ප නම්, ඔබ ඔබේ අනුමාන වෙනස් කරයි. එය සෑම තුන් වරක්ම එක් මාර්ගයකට ගියහොත්, ඔබ අනුමාන කරන්නේ එයමයි ...
වෙනත් වචන වලින් කිවහොත්, ඔබ රටාවක් හඳුනාගෙන එය අනුගමනය කිරීමට උත්සාහ කරයි. ශාඛා අනාවැකි කරුවන් ක්රියා කරන ආකාරය මෙය අඩු හෝ වැඩි ය.
බොහෝ යෙදුම්වල හොඳින් හැසිරෙන ශාඛා ඇත. එබැවින් නවීන ශාඛා අනාවැකි කරන්නන් සාමාන්යයෙන්> 90% පහර අනුපාත ලබා ගනී. නමුත් හඳුනාගත නොහැකි රටාවන් නොමැති අනපේක්ෂිත ශාඛාවන්ට මුහුණ දෙන විට, ශාඛා අනාවැකි කරන්නන් පාහේ නිෂ් .ල ය.
වැඩිදුර කියවීම: විකිපීඩියාව පිළිබඳ "ශාඛා අනාවැකි" ලිපිය .
ඉහළින් ඉඟි කර ඇති පරිදි, වැරදිකරු මෙය නම්-ප්රකාශය:
if (data[c] >= 128)
sum += data[c];
දත්ත 0 සහ 255 අතර ඒකාකාරව බෙදා හරින බව සැලකිල්ලට ගන්න. දත්ත වර්ග කළ විට, දළ වශයෙන් පළමු පුනරාවර්තනයන් if-statement වෙත ඇතුල් නොවනු ඇත. ඊට පසු, ඔවුන් සියල්ලන්ම if-statement වෙත ඇතුළු වනු ඇත.
ශාඛාව අඛණ්ඩව එකම දිශාවකට බොහෝ වාරයක් යන බැවින් මෙය ශාඛා අනාවැකි කරුවාට ඉතා මිත්රශීලී ය. සරල සංතෘප්ත කවුන්ටරයක් පවා ශාඛාව දිශාව මාරු කිරීමෙන් පසු පුනරාවර්තන කිහිපයක් හැර නිවැරදිව පුරෝකථනය කරයි.
ඉක්මන් දෘශ්යකරණය:
T = branch taken
N = branch not taken
data[] = 0, 1, 2, 3, 4, ... 126, 127, 128, 129, 130, ... 250, 251, 252, ...
branch = N N N N N ... N N T T T ... T T T ...
= NNNNNNNNNNNN ... NNNNNNNTTTTTTTTT ... TTTTTTTTTT (easy to predict)
කෙසේ වෙතත්, දත්ත සම්පුර්ණයෙන්ම අහඹු ලෙස සිදු වූ විට, ශාඛා අනාවැකි නිෂ් less ල වනු ඇත, එයට අහඹු දත්ත පුරෝකථනය කළ නොහැකි බැවිනි. මේ අනුව බොහෝ විට වැරදි අනාවැකි 50% ක් පමණ වනු ඇත (අහඹු ලෙස අනුමාන කිරීමට වඩා හොඳ නැත).
data[] = 226, 185, 125, 158, 198, 144, 217, 79, 202, 118, 14, 150, 177, 182, 133, ...
branch = T, T, N, T, T, T, T, N, T, N, N, T, T, T, N ...
= TTNTTTTNTNNTTTN ... (completely random - hard to predict)
ඉතින් කුමක් කළ හැකිද?
සම්පාදකයාට ශාඛාව කොන්දේසිගත පියවරක් ලෙස ප්රශස්තිකරණය කිරීමට නොහැකි නම්, කාර්ය සාධනය සඳහා කියවීමේ හැකියාව කැප කිරීමට ඔබ කැමති නම් ඔබට යම් යම් උපක්රම උත්සාහ කළ හැකිය.
ප්රතිස්ථාපනය කරන්න:
if (data[c] >= 128)
sum += data[c];
සමග:
int t = (data[c] - 128) >> 31;
sum += ~t & data[c];
මෙය ශාඛාව ඉවත් කර එය බිට්වේස් මෙහෙයුම් මගින් ප්රතිස්ථාපනය කරයි.
(මෙම අනවසරයෙන් මුල් if-statement ට සමාන නොවන බව සලකන්න. නමුත් මේ අවස්ථාවේ දී, එය සියලු ආදාන අගයන් සඳහා වලංගු වේ data[]
.)
මිණුම් සලකුණු: මූලික i7 920 @ 3.5 GHz
සී ++ - විෂුවල් ස්ටුඩියෝ 2010 - x64 නිකුතුව
// Branch - Random
seconds = 11.777
// Branch - Sorted
seconds = 2.352
// Branchless - Random
seconds = 2.564
// Branchless - Sorted
seconds = 2.587
ජාවා - නෙට්බීන්ස් 7.1.1 ජේඩීකේ 7 - x64
// Branch - Random
seconds = 10.93293813
// Branch - Sorted
seconds = 5.643797077
// Branchless - Random
seconds = 3.113581453
// Branchless - Sorted
seconds = 3.186068823
නිරීක්ෂණ:
- ශාඛාව සමඟ: වර්ග කළ හා වර්ග නොකළ දත්ත අතර විශාල වෙනසක් ඇත.
- හැක් සමඟ: වර්ග කළ සහ වර්ග නොකළ දත්ත අතර වෙනසක් නැත.
- C ++ නඩුවේදී, දත්ත වර්ග කරන විට හැක් යනු ශාඛාවට වඩා මන්දගාමී වේ.
සාමාන්ය ඇඟිල්ලේ රීතියක් නම් විවේචනාත්මක ලූපවල දත්ත මත යැපීම වළක්වා ගැනීමයි (මෙම උදාහරණය වැනි).
යාවත්කාලීන කිරීම:
X64 සමඟ -O3
හෝ -ftree-vectorize
මත ඇති GCC 4.6.1 මගින් කොන්දේසි සහිත පියවරක් ජනනය කළ හැකිය. එබැවින් වර්ග කළ හා වර්ග නොකළ දත්ත අතර වෙනසක් නැත - දෙකම වේගවත් ය.
(නැතහොත් තරමක් වේගයෙන්: දැනටමත්-හරිම නඩුව සඳහා, cmov
මන්දගාමී, විශේෂයෙන්ම පමණක් ගල්ෆ් තීරනාත්මක මාවතේ තබන එය නම් වෙනුවට කළ හැකි add
, විශේෂයෙන් ඉන්ටෙල් මත Broadwell එහිදී පෙර cmov
: 2 චක්රය පමාවක් ඇති මන්දගාමී -O2 වඩා gcc ප්රශස්තිකරණය ධජය -O3 වර්ගයන් කේතය )
VC ++ 2010 ට මෙම ශාඛාව සඳහා කොන්දේසි සහිත චලනයන් උත්පාදනය කළ නොහැක /Ox
.
ඉන්ටෙල් සී ++ කම්පයිලර් (අයිසීසී) 11 ආශ්චර්යමත් දෙයක් කරයි. එය වළළු දෙකක් අන්තර් හුවමාරු එමගින් කලින් කිව නොහැකි ශාඛා පිටත පුඩුවක් කිරීමට එසවීම,. එබැවින් එය වැරදි අනාවැකි වලට ප්රතිශක්තීකරණයක් පමණක් නොව, VC ++ සහ GCC මගින් ජනනය කළ හැකි ඕනෑම දෙයකට වඩා දෙගුණයක් වේගවත් වේ! වෙනත් වචන වලින් කිවහොත්, මිණුම් දණ්ඩ පරාජය කිරීම සඳහා අයිසීසී ටෙස්ට් ලූපයෙන් ප්රයෝජන ගත්තේය ...
ඔබ ඉන්ටෙල් සම්පාදකයාට ශාඛා රහිත කේතය ලබා දෙන්නේ නම්, එය පිටත දකුණට දෛශික කරයි ... එය ශාඛාව මෙන් වේගවත් වේ (ලූප් අන්තර් හුවමාරුව සමඟ).
පරිණත නවීන සම්පාදකයින්ට පවා කේත ප්රශස්තිකරණය කිරීමේ හැකියාව අනුව වෙනස් විය හැකි බව මෙයින් පෙනේ ...