Оптимизировать Буддхаброт

В настоящее время я работаю над собственной реализацией "Буддхаброт". Пока я использую std::thread-Класс из C++11 для одновременной работы через следующую итерацию:

void iterate(float *res){
//generate starting point
std::default_random_engine generator;
std::uniform_real_distribution<double> distribution(-1.5,1.5);

double ReC,ImC;
double ReS,ImS,ReS_;
unsigned int steps;

unsigned int visitedPos[maxCalcIter];

unsigned int succSamples(0);

//iterate over it
while(succSamples < samplesPerThread){
    steps = 0;
    ReC = distribution(generator)-0.4;
    ImC = distribution(generator);
    double p(sqrt((ReC-0.25)*(ReC-0.25) + ImC*ImC));
    while (( ((ReC+1)*(ReC+1) + ImC*ImC) < 0.0625) || (ReC < p - 2*p*p + 0.25)){
        ReC = distribution(generator)-0.4;
        ImC = distribution(generator);
        p = sqrt((ReC-0.25)*(ReC-0.25) + ImC*ImC);
    }
    ReS = ReC;
    ImS = ImC;
    for (unsigned int j = maxCalcIter; (ReS*ReS + ImS*ImS < 4)&&(j--); ){
        ReS_ = ReS;
        ReS *= ReS;
        ReS += ReC - ImS*ImS;
        ImS *= 2*ReS_;
        ImS += ImC;
        if ((ReS+0.5)*(ReS+0.5) + ImS*ImS < 4){
            visitedPos[steps] = int((ReS+2.5)*0.25*outputSize)*outputSize + int((ImS+2)*0.25*outputSize);

        }
        steps++;

    }
    if ((steps > minCalcIter)&&(ReS*ReS + ImS*ImS > 4)){
        succSamples++;
        for (int j = steps; j--;){
            //std::cout << visitedPos[j] << std::endl;
            res[visitedPos[j]]++;
        }
    }
}
}

Так что в основном я работаю в каждом потоке так долго, что я сгенерировал достаточно траекторий достаточной длины, которая, как ожидается, занимает одинаковое время в каждом потоке.

Но у меня действительно есть ощущение, что эта функция может быть мне неоптимизирована, поскольку ее код очень хорошо читается. Кто-нибудь может придумать какие-нибудь модные оптимизации? Когда дело доходит до компиляции, я просто использую:g++ -O4 -std=c++11 -I/usr/include/OpenEXR/ -L/usr/lib64/ -lHalf -lIlmImf -lm buddha_cpu.cpp -o buddha_cpu

Так что любые намеки на сокращение еще нескольких цифр / сек будут очень полезны. Также любые ссылки на дальнейшую литературу приветствуются.

1 ответ

Вы это проверяли? -O4 быстрее чем -O2? Выше О2 не уверен. Кроме того, если этот сборник только для вас, попробуйте -march=native, Это позволит использовать преимущества вашей конкретной архитектуры ЦП, но полученный двоичный файл может привести к сбою с SIGSEV на старых / разных машинах.

Вы не показали ни одной темы, если я правильно вижу. Убедитесь, что ваши потоки не записывают в память места одной и той же строки кэша. Запись областей памяти в одну и ту же строку кэша из разных потоков заставляет ядра ЦП синхронизировать свой кэш - это огромное снижение производительности.

Другие вопросы по тегам