यहाँ कोड का एक वास्तविक टुकड़ा है कि मैं एक बड़ी परियोजना के बाहर निकाला गया है। (क्षमा करें, यह सबसे छोटा है जिसे मैं पा सकता हूं जिसमें प्रीफेचिंग से एक उल्लेखनीय गति थी।) यह कोड एक बहुत बड़ा डेटा ट्रांसफर करता है।
यह उदाहरण एसएसई प्रीफेच निर्देशों का उपयोग करता है, जो कि जीसीसी उत्सर्जित करने जैसा ही हो सकता है।
इस उदाहरण को चलाने के लिए, आपको इसे x64 के लिए संकलित करने और 4GB से अधिक स्मृति होने की आवश्यकता होगी। आप इसे छोटे डेटासाइज के साथ चला सकते हैं, लेकिन यह समय के लिए बहुत तेज़ होगा।
#include <iostream>
using std::cout;
using std::endl;
#include <emmintrin.h>
#include <malloc.h>
#include <time.h>
#include <string.h>
#define ENABLE_PREFETCH
#define f_vector __m128d
#define i_ptr size_t
inline void swap_block(f_vector *A,f_vector *B,i_ptr L){
// To be super-optimized later.
f_vector *stop = A + L;
do{
f_vector tmpA = *A;
f_vector tmpB = *B;
*A++ = tmpB;
*B++ = tmpA;
}while (A < stop);
}
void transpose_even(f_vector *T,i_ptr block,i_ptr x){
// Transposes T.
// T contains x columns and x rows.
// Each unit is of size (block * sizeof(f_vector)) bytes.
//Conditions:
// - 0 < block
// - 1 < x
i_ptr row_size = block * x;
i_ptr iter_size = row_size + block;
// End of entire matrix.
f_vector *stop_T = T + row_size * x;
f_vector *end = stop_T - row_size;
// Iterate each row.
f_vector *y_iter = T;
do{
// Iterate each column.
f_vector *ptr_x = y_iter + block;
f_vector *ptr_y = y_iter + row_size;
do{
#ifdef ENABLE_PREFETCH
_mm_prefetch((char*)(ptr_y + row_size),_MM_HINT_T0);
#endif
swap_block(ptr_x,ptr_y,block);
ptr_x += block;
ptr_y += row_size;
}while (ptr_y < stop_T);
y_iter += iter_size;
}while (y_iter < end);
}
int main(){
i_ptr dimension = 4096;
i_ptr block = 16;
i_ptr words = block * dimension * dimension;
i_ptr bytes = words * sizeof(f_vector);
cout << "bytes = " << bytes << endl;
// system("pause");
f_vector *T = (f_vector*)_mm_malloc(bytes,16);
if (T == NULL){
cout << "Memory Allocation Failure" << endl;
system("pause");
exit(1);
}
memset(T,0,bytes);
// Perform in-place data transpose
cout << "Starting Data Transpose... ";
clock_t start = clock();
transpose_even(T,block,dimension);
clock_t end = clock();
cout << "Done" << endl;
cout << "Time: " << (double)(end - start)/CLOCKS_PER_SEC << " seconds" << endl;
_mm_free(T);
system("pause");
}
जब मैं इसके साथ ENABLE_PREFETCH सक्षम चलाने के लिए, यह उत्पादन होता है:
bytes = 4294967296
Starting Data Transpose... Done
Time: 0.822 seconds
Press any key to continue . . .
तो वहाँ एक:
bytes = 4294967296
Starting Data Transpose... Done
Time: 0.725 seconds
Press any key to continue . . .
जब मैं ENABLE_PREFETCH विकलांग के साथ इसे चलाने के लिए, यह उत्पादन होता है Prefetching से 13% speedup।
संपादित करें:
यहाँ कुछ और परिणाम:
Operating System: Windows 7 Professional/Ultimate
Compiler: Visual Studio 2010 SP1
Compile Mode: x64 Release
Intel Core i7 860 @ 2.8 GHz, 8 GB DDR3 @ 1333 MHz
Prefetch : 0.868
No Prefetch: 0.960
Intel Core i7 920 @ 3.5 GHz, 12 GB DDR3 @ 1333 MHz
Prefetch : 0.725
No Prefetch: 0.822
Intel Core i7 2600K @ 4.6 GHz, 16 GB DDR3 @ 1333 MHz
Prefetch : 0.718
No Prefetch: 0.796
2 x Intel Xeon X5482 @ 3.2 GHz, 64 GB DDR2 @ 800 MHz
Prefetch : 2.273
No Prefetch: 2.666
दिलचस्प। दुर्भाग्यवश मैंने दो मशीनों पर परीक्षण किया ("कोर 2 डुओ" के साथ मैकबुक प्रो और "क्वाड-कोर एएमडी ओपर्टन प्रोसेसर 2376" के साथ एक लिनक्स मशीन) मुझे दो संस्करणों के बीच महत्वपूर्ण अंतर नहीं मिला। मुझे संदेह है कि इसे कैश आकार के साथ करना है - ऐसा लगता है कि आपके पास उन दोनों की तुलना में बेहतर मशीन है। तुम क्या सोचते हो? –
मेरी मशीन कोर i7 920 @ 3.5 गीगाहर्ट्ज है। 8 एमबी एल 3 कैश। यह 10% स्पीडअप मैंने परीक्षण की 3 अन्य मशीनों पर कम या कम संगत है: कोर i7 2600K @ 4.6 गीगाहर्ट्ज, और 2 एक्स ज़ीऑन X5482 @ 3.2 गीगाहर्ट्ज। लेकिन मैं स्वीकार करूंगा कि मैंने कभी लैपटॉप या एएमडी मशीन पर इसका परीक्षण नहीं किया है। – Mysticial
मैंने अभी परीक्षण किया है कि मैंने परीक्षण की सभी 4 मशीनों पर बेंचमार्क के साथ अपना जवाब संपादित किया। वे सभी इंटेल डेस्कटॉप/वर्कस्टेशन हैं। तो यह कारण हो सकता है। मैंने परीक्षण नहीं किया कि आपका तीसरा बिंदु है या नहीं। यह हो सकता है कि इसे स्मृति पहुंच के साथ प्रतिस्थापित करने से एक ही परिणाम उत्पन्न हो सके। – Mysticial