सी ++ 11 के यादृच्छिक मॉड्यूल का उपयोग करना, मैं जब एक uniform_real_distribution
के साथ संयोजन में std::mt19937
(32 और 64 बिट संस्करण) का उपयोग कर एक अजीब प्रदर्शन ड्रॉप का सामना करना पड़ा (नाव या डबल, कोई फर्क नहीं पड़ता) । की तुलना में एक ग्राम ++ संकलन, यह परिमाण धीमी की एक आदेश की तुलना में अधिक है!बजना प्रदर्शन ड्रॉप
अपराधी सिर्फ एमटी जनरेटर, यह एक uniform_int_distribution
साथ तेज है के रूप में नहीं है। और यह uniform_real_distribution
में एक सामान्य कमी थी जिसके कारण default_random_engine
जैसे अन्य जनरेटर के साथ तेज है के बाद से नहीं है। बस उस विशिष्ट संयोजन अजीब धीमी है।
मैं इंट्रिनिक्स से बहुत परिचित नहीं हूं, लेकिन मेर्सन ट्विस्टर एल्गोरिदम कम या ज्यादा सख्ती से परिभाषित किया गया है, इसलिए कार्यान्वयन में एक अंतर मुझे इस अंतर के लिए जिम्मेदार नहीं ठहरा सकता है?
gcc 4.8.1
runtime_int_default: 185.6
runtime_int_mt: 179.198
runtime_int_mt_64: 175.195
runtime_float_default: 45.375
runtime_float_mt: 58.144
runtime_float_mt_64: 94.188
clang 3.4
runtime_int_default: 215.096
runtime_int_mt: 201.064
runtime_int_mt_64: 199.836
runtime_float_default: 55.143
runtime_float_mt: 744.072 <--- this and
runtime_float_mt_64: 783.293 <- this is slow
कार्यक्रम इस पैदा करते हैं और अपने आप को बाहर की कोशिश करने के:
#include <iostream>
#include <vector>
#include <chrono>
#include <random>
template< typename T_rng, typename T_dist>
double time_rngs(T_rng& rng, T_dist& dist, int n){
std::vector< typename T_dist::result_type > vec(n, 0);
auto t1 = std::chrono::high_resolution_clock::now();
for (int i = 0; i < n; ++i)
vec[i] = dist(rng);
auto t2 = std::chrono::high_resolution_clock::now();
auto runtime = std::chrono::duration_cast<std::chrono::microseconds>(t2-t1).count()/1000.0;
auto sum = vec[0]; //access to avoid compiler skipping
return runtime;
}
int main(){
const int n = 10000000;
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine rng_default(seed);
std::mt19937 rng_mt (seed);
std::mt19937_64 rng_mt_64 (seed);
std::uniform_int_distribution<int> dist_int(0,1000);
std::uniform_real_distribution<float> dist_float(0.0, 1.0);
// print max values
std::cout << "rng_default_random.max(): " << rng_default.max() << std::endl;
std::cout << "rng_mt.max(): " << rng_mt.max() << std::endl;
std::cout << "rng_mt_64.max(): " << rng_mt_64.max() << std::endl << std::endl;
std::cout << "runtime_int_default: " << time_rngs(rng_default, dist_int, n) << std::endl;
std::cout << "runtime_int_mt: " << time_rngs(rng_mt_64, dist_int, n) << std::endl;
std::cout << "runtime_int_mt_64: " << time_rngs(rng_mt_64, dist_int, n) << std::endl;
std::cout << "runtime_float_default: " << time_rngs(rng_default, dist_float, n) << std::endl;
std::cout << "runtime_float_mt: " << time_rngs(rng_mt, dist_float, n) << std::endl;
std::cout << "runtime_float_mt_64: " << time_rngs(rng_mt_64, dist_float, n) << std::endl;
}
clang++ -O3 -std=c++11 random.cpp
के माध्यम से संकलन को मापने कार्यक्रम पीछा कर रहा है, लेकिन यहाँ बजना 3.4 और जीसीसी 4.8.1 एक 64 बिट Linux मशीन पर के लिए मेरे परिणाम हैं या क्रमशः जी ++। कोई विचार?
संपादित करें: अंत में, माथीउ एम के लिए एक महान विचार था: अपराधी को इनलाइन है, या बल्कि एक उसके अभाव। क्लैंग इनलाइनिंग सीमा को बढ़ाने से प्रदर्शन जुर्माना समाप्त हो गया। वास्तव में मुझे कई प्रदर्शन विषमताओं का सामना करना पड़ा। धन्यवाद, मैंने कुछ नया सीखा।
हो सकता है कि आप चीजों को थोड़ा सा प्रोफाइल करना चाहते हैं (उदा। कॉलग्रिंड के साथ) और जेनरेट असेंबलर की तुलना करें ... – PlasmaHH
मैं इसे 'float_mt'64' के लिए नहीं बल्कि 'float_mt' केस के लिए पुन: उत्पन्न कर सकता हूं। मैंने फेडोरा 20 64-बिट पर clang3.4 के साथ अपना कोड इस्तेमाल किया। –
एक बग रिपोर्ट के बाद कहने के लिए जा रहा था लेकिन मैंने देखा कि आप पहले से ही किया था, http://llvm.org/bugs/show_bug.cgi?id=19542 – pyCthon