අවලංගු කරන ලද පාවෙන ලක්ෂ්යයේ ලෝකයට සාදරයෙන් පිළිගනිමු ! ඔවුන්ට කාර්ය සාධනය විනාශ කළ හැකිය !!!
පාවෙන ලක්ෂ්ය නිරූපණයෙන් ශුන්යයට ඉතා ආසන්නව අමතර අගයන් ලබා ගැනීම සඳහා ඩෙනෝමල් (හෝ උප සාමාන්ය) සංඛ්යා කඩුල්ලක් වේ. Denormalized ඉපිලුම් ලක්ෂ්ය මත මෙහෙයුම් කළ හැකි මන්දගාමී වාර සිය ගණනක් දස සාමාන්යකරණයට ඉපිලුම් ලක්ෂ්ය මත වඩා. මෙයට හේතුව බොහෝ සකසනයන්ට ඒවා කෙලින්ම හැසිරවිය නොහැකි අතර මයික්රෝ කේත භාවිතයෙන් ඒවා කොටු කර විසඳිය යුතුය.
ඔබ අනුකරණ 10,000 පසු අංක මුද්රණය කරයි නම්, ඔබ ඔවුන් යන්න මත පදනම් විවිධ වටිනාකම් තුලට ඇති බව පෙනෙනු ඇත 0
හෝ 0.1
භාවිතා කරනු ඇත.
X64 මත සම්පාදනය කරන ලද පරීක්ෂණ කේතය මෙන්න:
int main() {
double start = omp_get_wtime();
const float x[16]={1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0,2.1,2.2,2.3,2.4,2.5,2.6};
const float z[16]={1.123,1.234,1.345,156.467,1.578,1.689,1.790,1.812,1.923,2.034,2.145,2.256,2.367,2.478,2.589,2.690};
float y[16];
for(int i=0;i<16;i++)
{
y[i]=x[i];
}
for(int j=0;j<9000000;j++)
{
for(int i=0;i<16;i++)
{
y[i]*=x[i];
y[i]/=z[i];
#ifdef FLOATING
y[i]=y[i]+0.1f;
y[i]=y[i]-0.1f;
#else
y[i]=y[i]+0;
y[i]=y[i]-0;
#endif
if (j > 10000)
cout << y[i] << " ";
}
if (j > 10000)
cout << endl;
}
double end = omp_get_wtime();
cout << end - start << endl;
system("pause");
return 0;
}
ප්රතිදානය:
#define FLOATING
1.78814e-007 1.3411e-007 1.04308e-007 0 7.45058e-008 6.70552e-008 6.70552e-008 5.58794e-007 3.05474e-007 2.16067e-007 1.71363e-007 1.49012e-007 1.2666e-007 1.11759e-007 1.04308e-007 1.04308e-007
1.78814e-007 1.3411e-007 1.04308e-007 0 7.45058e-008 6.70552e-008 6.70552e-008 5.58794e-007 3.05474e-007 2.16067e-007 1.71363e-007 1.49012e-007 1.2666e-007 1.11759e-007 1.04308e-007 1.04308e-007
//#define FLOATING
6.30584e-044 3.92364e-044 3.08286e-044 0 1.82169e-044 1.54143e-044 2.10195e-044 2.46842e-029 7.56701e-044 4.06377e-044 3.92364e-044 3.22299e-044 3.08286e-044 2.66247e-044 2.66247e-044 2.24208e-044
6.30584e-044 3.92364e-044 3.08286e-044 0 1.82169e-044 1.54143e-044 2.10195e-044 2.45208e-029 7.56701e-044 4.06377e-044 3.92364e-044 3.22299e-044 3.08286e-044 2.66247e-044 2.66247e-044 2.24208e-044
දෙවන ධාවනයේදී සංඛ්යා ශුන්යයට ඉතා ආසන්න වන්නේ කෙසේදැයි බලන්න.
සාමාන්යකරණය කරන ලද සංඛ්යා සාමාන්යයෙන් දුර්ලභ වන අතර එබැවින් බොහෝ සකසනයන් ඒවා කාර්යක්ෂමව හැසිරවීමට උත්සාහ නොකරයි.
කේතයේ ආරම්භයට මෙය එකතු කිරීමෙන් අප විසින් ශුන්යයට හරවා යැවුවහොත්, මේ සඳහා සංඛ්යාත සංඛ්යා සමඟ සෑම දෙයක්ම ඇති බව පෙන්වීමට :
_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
එවිට ඇති අනුවාදය 0
තවදුරටත් 10x මන්දගාමී නොවන අතර ඇත්ත වශයෙන්ම වේගවත් වේ. (මේ සඳහා කේතය SSE සක්රීය කිරීම සමඟ සම්පාදනය කිරීම අවශ්ය වේ.)
මෙයින් අදහස් කරන්නේ මෙම අමුතු අඩු නිරවද්යතාව පාහේ ශුන්ය අගයන් භාවිතා කරනවා වෙනුවට, අපි ඒ වෙනුවට ශුන්යයට හැරෙන බවයි.
වේලාවන්: මූලික i7 920 @ 3.5 GHz:
// Don't flush denormals to zero.
0.1f: 0.564067
0 : 26.7669
// Flush denormals to zero.
0.1f: 0.587117
0 : 0.341406
අවසානයේදී, මෙය සැබවින්ම එය පූර්ණ සංඛ්යාවක් හෝ පාවෙන ලක්ෂ්යයක් සමග කිසිදු සම්බන්ධයක් නැත. මෙම 0
හෝ 0.1f
/ වළළු දෙකම ලේඛනයක් පිටත බවට ගබඩා පරිවර්තනය කර ඇත. එබැවින් එය කාර්ය සාධනය කෙරෙහි කිසිදු බලපෑමක් ඇති නොකරයි.