मैं कुछ परीक्षण भाग गया और यहाँ कोड मैं परीक्षण किया है:
delegate(float[] inout)
{ // My Original Code
float[][] tempbuf = new float[2][];
int length = inout.Length/2;
for (int c = 0; c < 2; c++)
{
tempbuf[c] = new float[length];
for (int i = 0, offset = c; i < tempbuf[c].Length; i++, offset += 2)
tempbuf[c][i] = inout[offset];
}
}
delegate(float[] inout)
{ // jerryjvl's recommendation: loop unrolling
float[][] tempbuf = new float[2][];
int length = inout.Length/2;
for (int c = 0; c < 2; c++)
tempbuf[c] = new float[length];
for (int ix = 0, i = 0; ix < length; ix++)
{
tempbuf[0][ix] = inout[i++];
tempbuf[1][ix] = inout[i++];
}
}
delegate(float[] inout)
{ // Unsafe Code
unsafe
{
float[][] tempbuf = new float[2][];
int length = inout.Length/2;
fixed (float* buffer = inout)
for (int c = 0; c < 2; c++)
{
tempbuf[c] = new float[length];
float* offset = buffer + c;
fixed (float* buffer2 = tempbuf[c])
{
float* p = buffer2;
for (int i = 0; i < length; i++, offset += 2)
*p++ = *offset;
}
}
}
}
delegate(float[] inout)
{ // Modifying my original code to see if the compiler is not as smart as i think it is.
float[][] tempbuf = new float[2][];
int length = inout.Length/2;
for (int c = 0; c < 2; c++)
{
float[] buf = tempbuf[c] = new float[length];
for (int i = 0, offset = c; i < buf.Length; i++, offset += 2)
buf[i] = inout[offset];
}
}
और परिणाम: (बफर आकार = 2^17, नंबर पुनरावृत्तियों परीक्षण प्रति समय समाप्त हो गया = 200)
Average for test #1: 0.001286 seconds +/- 0.000026
Average for test #2: 0.001193 seconds +/- 0.000025
Average for test #3: 0.000686 seconds +/- 0.000009
Average for test #4: 0.000847 seconds +/- 0.000008
Average for test #1: 0.001210 seconds +/- 0.000012
Average for test #2: 0.001048 seconds +/- 0.000012
Average for test #3: 0.000690 seconds +/- 0.000009
Average for test #4: 0.000883 seconds +/- 0.000011
Average for test #1: 0.001209 seconds +/- 0.000015
Average for test #2: 0.001060 seconds +/- 0.000013
Average for test #3: 0.000695 seconds +/- 0.000010
Average for test #4: 0.000861 seconds +/- 0.000009
मैं प्रत्येक परीक्षण के समान परिणाम मिला। स्पष्ट रूप से असुरक्षित कोड सबसे तेज़ है, लेकिन मुझे यह देखकर आश्चर्य हुआ कि सीएलएस यह नहीं समझ सका कि यह जंजीर सरणी से निपटने के दौरान इंडेक्स चेक को छोड़ सकता है। शायद कोई मेरे परीक्षण को अनुकूलित करने के अधिक तरीकों के बारे में सोच सकता है।
संपादित करें: मैंने असुरक्षित कोड के साथ अनलॉक करने की कोशिश की और इसका कोई प्रभाव नहीं पड़ा।
delegate(float[] inout)
{
float[][] tempbuf = new float[2][];
int length = inout.Length/2;
float[] tempbuf0 = tempbuf[0] = new float[length];
float[] tempbuf1 = tempbuf[1] = new float[length];
for (int ix = 0, i = 0; ix < length; ix++)
{
tempbuf0[ix] = inout[i++];
tempbuf1[ix] = inout[i++];
}
}
परिणाम भी कर रहे हैं 1% अंतर के साथ एक हिट याद आती है की तुलना में परीक्षण # 4: मैं भी पाश unrolling विधि के अनुकूलन की कोशिश की। टेस्ट # 4 अब तक जाने का मेरा सबसे अच्छा तरीका है।
जैसा कि मैंने एक दूसरे जाँच जोड़ने के बाद से jerryjvl, समस्या नहीं सूचकांक इनपुट बफर जाँच करने के लिए सीएलएस हो रही है, बताया (& & ऑफसेट < inout.Length) यह धीमी हो जाएगी ...
संपादित करें 2 : मैं परीक्षण आईडीई में पहले, इसलिए यहाँ भाग गया परिणाम में नहीं हैं:
2^17 items, repeated 200 times
******************************************
Average for test #1: 0.000533 seconds +/- 0.000017
Average for test #2: 0.000527 seconds +/- 0.000016
Average for test #3: 0.000407 seconds +/- 0.000008
Average for test #4: 0.000374 seconds +/- 0.000008
Average for test #5: 0.000424 seconds +/- 0.000009
2^17 items, repeated 200 times
******************************************
Average for test #1: 0.000547 seconds +/- 0.000016
Average for test #2: 0.000732 seconds +/- 0.000020
Average for test #3: 0.000423 seconds +/- 0.000009
Average for test #4: 0.000360 seconds +/- 0.000008
Average for test #5: 0.000406 seconds +/- 0.000008
2^18 items, repeated 200 times
******************************************
Average for test #1: 0.001295 seconds +/- 0.000036
Average for test #2: 0.001283 seconds +/- 0.000020
Average for test #3: 0.001085 seconds +/- 0.000027
Average for test #4: 0.001035 seconds +/- 0.000025
Average for test #5: 0.001130 seconds +/- 0.000025
2^18 items, repeated 200 times
******************************************
Average for test #1: 0.0seconds +/- 0.000026
Average for test #2: 0.001319 seconds +/- 0.000023
Average for test #3: 0.001309 seconds +/- 0.000025
Average for test #4: 0.001191 seconds +/- 0.000026
Average for test #5: 0.001196 seconds +/- 0.000022
Test#1 = My Original Code
Test#2 = Optimized safe loop unrolling
Test#3 = Unsafe code - loop unrolling
Test#4 = Unsafe code
Test#5 = My Optimized Code
ऐसा लगता है कि पाश unrolling अनुकूल नहीं है। मेरा अनुकूलित कोड अभी भी असुरक्षित कोड की तुलना में जाने के लिए और केवल 10% अंतर के साथ मेरा सबसे अच्छा तरीका है। अगर मैं केवल संकलक को बता सकता हूं कि (i < buf.Length) का तात्पर्य है कि (ऑफसेट < इनआउट। लम्बाई), यह चेक (इनआउट [ऑफसेट]) को छोड़ देगा और मुझे मूल रूप से असुरक्षित प्रदर्शन मिलेगा।
क्या आप जो भी करने की कोशिश कर रहे हैं उसका एक कोड खंड प्रदान कर सकते हैं? आप जो हासिल करने की कोशिश कर रहे हैं उसके ठोस नमूने के साथ आपकी सहायता करने के लिए यह बहुत आसान होगा। – jerryjvl