Решение: Очевидно, виновником было использование floor()
, производительность которого в glibc зависит от ОС.
Это вопрос к предыдущему: Та же программа в Linux быстрее, чем в Windows - почему?
У меня есть небольшая программа на C ++, которая при компиляции с nuwen gcc 4.6.1 работает намного быстрее в Wine, чем в Windows XP (на том же компьютере). Вопрос: почему это происходит?
Время составляет ~ 15,8 и 25,9 секунды для Wine и Windows соответственно. Обратите внимание, что я имею в виду тот же исполняемый файл , а не только одну и ту же программу на C ++.
Исходный код находится в конце поста. Скомпилированный исполняемый файл здесь (если вы мне достаточно доверяете).
Эта конкретная программа не делает ничего полезного, это всего лишь минимальный пример, созданный мной из более крупной программы. Пожалуйста, посмотрите этот другой вопрос , чтобы узнать более точный сравнительный анализ исходной программы (важно !!) и исключить наиболее распространенные возможности (такие как другие программы, загружающие ЦП в Windows, штраф за запуск процесса, разницу в системе). вызовы, такие как выделение памяти). Также обратите внимание, что в то время как здесь я использовал rand()
для простоты, в оригинале я использовал свой собственный RNG, который, как я знаю, не выделяет кучу.
Причина, по которой я открыл новый вопрос по этой теме, заключается в том, что теперь я могу опубликовать реальный пример упрощенного кода для воспроизведения явления.
Код:
#include <cstdlib>
#include <cmath>
int irand(int top) {
return int(std::floor((std::rand() / (RAND_MAX + 1.0)) * top));
}
template<typename T>
class Vector {
T *vec;
const int sz;
public:
Vector(int n) : sz(n) {
vec = new T[sz];
}
~Vector() {
delete [] vec;
}
int size() const { return sz; }
const T & operator [] (int i) const { return vec[i]; }
T & operator [] (int i) { return vec[i]; }
};
int main() {
const int tmax = 20000; // increase this to make it run longer
const int m = 10000;
Vector<int> vec(150);
for (int i=0; i < vec.size(); ++i)
vec[i] = 0;
// main loop
for (int t=0; t < tmax; ++t)
for (int j=0; j < m; ++j) {
int s = irand(100) + 1;
vec[s] += 1;
}
return 0;
}
UPDATE
Похоже, что если я заменю irand()
выше чем-то детерминированным, таким как
int irand(int top) {
static int c = 0;
return (c++) % top;
}
тогда разница во времени исчезнет. Хотелось бы отметить, что в моей исходной программе я использовал другой ГСЧ, а не систему rand()
. Сейчас я копаюсь в источнике этого.
ОБНОВЛЕНИЕ 2
Теперь я заменил функцию irand()
эквивалентом того, что имел в исходной программе. Он немного длинен (алгоритм взят из Числовые рецепты ), но цель состояла в том, чтобы показать, что никакие системные библиотеки не вызываются явно (кроме как через floor()
). Тем не менее разница во времени все еще есть!
Может быть, floor()
может быть виноват? Или компилятор генерирует вызовы к чему-то еще?
class ran1 {
static const int table_len = 32;
static const int int_max = (1u << 31) - 1;
int idum;
int next;
int *shuffle_table;
void propagate() {
const int int_quo = 1277731;
int k = idum/int_quo;
idum = 16807*(idum - k*int_quo) - 2836*k;
if (idum < 0)
idum += int_max;
}
public:
ran1() {
shuffle_table = new int[table_len];
seedrand(54321);
}
~ran1() {
delete [] shuffle_table;
}
void seedrand(int seed) {
idum = seed;
for (int i = table_len-1; i >= 0; i--) {
propagate();
shuffle_table[i] = idum;
}
next = idum;
}
double frand() {
int i = next/(1 + (int_max-1)/table_len);
next = shuffle_table[i];
propagate();
shuffle_table[i] = idum;
return next/(int_max + 1.0);
}
} rng;
int irand(int top) {
return int(std::floor(rng.frand() * top));
}