Решение: По-видимому, виновным было использование floor ()
, производительность которого оказывается ниже быть зависимым от ОС в glibc.
Это следующий вопрос к предыдущему: Та же программа быстрее в Linux, чем в Windows - почему?
У меня есть небольшая программа на C ++, которая при компиляции с nuwen gcc 4.6.1 , работает в Wine намного быстрее, чем Windows XP (на том же компьютере).Вопрос: почему это происходит?
Время составляет ~ 15,8 и 25,9 секунды для Wine и Windows соответственно. Обратите внимание, что я говорю об одном и том же исполняемом файле , а не только об одной и той же программе на C ++.
Исходный код в конце поста. Скомпилированный исполняемый файл находится здесь (если вы мне достаточно доверяете).
Эта конкретная программа не делает ничего полезного, это просто минимальный пример, взятый из более крупной программы, которая у меня есть. См. этот другой вопрос для более точного тестирования исходной программы (важно !!) и наиболее распространенных исключенных возможностей (например, другие программы, загружающие ЦП в Windows, штраф за запуск процесса, разница в системе вызовы, такие как выделение памяти). Также обратите внимание, что хотя здесь я использовал rand ()
для простоты, в оригинале я использовал свой собственный RNG, который, как я знаю, не выделяет кучу.
Причина, по которой я открыл новый вопрос по этой теме, заключается в том, что теперь я могу опубликовать реальный упрощенный пример кода для воспроизведения этого явления.
Код:
#include
#include
int irand(int top) {
return int(std::floor((std::rand() / (RAND_MAX + 1.0)) * top));
}
template
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 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;
}
ОБНОВЛЕНИЕ
Кажется, что если я заменю irand ()
выше чем-то детерминированным, например
int irand(int top) {
static int c = 0;
return (c++) % top;
}
, тогда разница во времени исчезнет. Однако я хотел бы отметить, что в моей исходной программе я использовал другой ГСЧ, а не систему rand ()
. Я сейчас вникаю в источник этого.
ОБНОВЛЕНИЕ 2
Теперь я заменил функцию irand ()
эквивалентом того, что было в исходной программе.Это немного длинновато (алгоритм взят из Numerical Recipes ), но суть в том, чтобы показать, что никакие системные библиотеки не вызываются явно (кроме, возможно, через 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));
}