Следующий код выполняется в 200 раз медленнее в Mac OS X, чем в Linux.Я не знаю почему, и проблема не кажется тривиальной.Я подозреваю ошибку в gcc на Mac или в Mac OS X или в моем оборудовании.
Код разветвляется процесс, который копирует таблицу страниц, но не память на MacOS X. Память копируется при записи, что происходит в цикле for в конце метода run.Там, для первых 4 вызовов run, все страницы должны быть скопированы, потому что каждая страница затронута.Для выполнения вторых 4 вызовов, когда пропуск составляет 512, необходимо копировать каждую вторую страницу, так как каждая вторая страница затрагивается.Интуитивно понятно, что первые 4 звонка должны занимать примерно вдвое больше времени, чем вторые 4 звонка, что совершенно не так.Для меня вывод программы следующий:
169.655ms
670.559ms
2784.18ms
16007.1ms
16.207ms
25.018ms
42.712ms
79.676ms
В Linux это
5.306ms
10.69ms
20.91ms
41.042ms
6.115ms
12.203ms
23.939ms
40.663ms
Общее время выполнения в Mac OS X составляет примерно 20 секунд, в Linux - около 0,5 секунды.для одной и той же программы оба раза компилируется с помощью gcc.Я пытался скомпилировать версию для Mac OS с gcc4, 4.2 и 4.4 - без изменений.
Есть идеи?
Код:
#include <stdint.h>
#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <cstring>
#include <cstdlib>
#include <sys/time.h>
using namespace std;
class Timestamp
{
private:
timeval time;
public:
Timestamp() { gettimeofday(&time,0); }
double operator-(const Timestamp& other) const { return static_cast<double>((static_cast<long long>(time.tv_sec)*1000000+(time.tv_usec))-(static_cast<long long>(other.time.tv_sec)*1000000+(other.time.tv_usec)))/1000.0; }
};
class ForkCoW
{
public:
void run(uint64_t size, uint64_t skip) {
// allocate and initialize array
void* arrayVoid;
posix_memalign(&arrayVoid, 4096, sizeof(uint64_t)*size);
uint64_t* array = static_cast<uint64_t*>(arrayVoid);
for (uint64_t i = 0; i < size; ++i)
array[i] = 0;
pid_t p = fork();
if (p == 0)
sleep(99999999);
if (p < 0) {
cerr << "ERRROR: Fork failed." << endl;
exit(-1);
}
{
Timestamp start;
for (uint64_t i = 0; i < size; i += skip) {
array[i] = 1;
}
Timestamp stop;
cout << (stop-start) << "ms" << endl;
}
kill(p,SIGTERM);
}
};
int main(int argc, char* argv[]) {
ForkCoW f;
f.run(1ull*1000*1000, 512);
f.run(2ull*1000*1000, 512);
f.run(4ull*1000*1000, 512);
f.run(8ull*1000*1000, 512);
f.run(1ull*1000*1000, 513);
f.run(2ull*1000*1000, 513);
f.run(4ull*1000*1000, 513);
f.run(8ull*1000*1000, 513);
}