Разочаровывающая производительность в Ubuntu для вычислительной нагрузки - PullRequest
6 голосов
/ 23 февраля 2012

Я обнаружил довольно низкую производительность при выполнении некоторого вычислительного кода под Ubuntu на совершенно новой машине безголовой рабочей станции, которую я использую для научных вычислений. Я заметил разницу в скорости выполнения небольшого сложного кода на Ubuntu по сравнению с моим старым ноутбуком Mac, который я использую для разработки. Тем не менее, мне удалось отогнать его до невероятно простого примера, который все еще демонстрирует улучшения, меньшие, чем стелар, по сравнению с моей старой машиной:

#include <stdio.h>
#include <math.h>

int main() {
        double res = 0.0;
        for(int i=1; i<200000000; i++) {
                res += exp((double) 100.0/i);
        }
        printf("%lf", res);
        return(0);
}

Теперь Mac - это почти 5-летний Core 2 Duo MacBook Pro с частотой 2,4 ГГц, работающий под управлением OS X 10.5, который запускает этот код примерно за 6,8 секунды. Однако на новом Core i7 Dell с частотой 3,4 ГГц, работающем под управлением Ubuntu 11.10, это занимает около 6,1 с! Может кто-нибудь объяснить мне, что здесь происходит, потому что абсурдно, что почти 5-летний ноутбук находится в пределах 10% от совершенно новой настольной рабочей станции? Это еще более абсурдно, потому что я вижу, что Core i7 с турбонаддувом достигает почти 4 ГГц с помощью инструментов мониторинга!

Mac скомпилирован с:

gcc -o test test.c -std=gnu99 -arch x86_64 -O2

Ubuntu скомпилировано с:

gcc -o test test.c -std=gnu99 -m64 -O2 -lm

Спасибо

Louis

Ответы [ 6 ]

3 голосов
/ 23 февраля 2012

абсурдно, что почти 5-летний ноутбук находится в пределах 10% от совершенно новой настольной рабочей станции

Имейте в виду, что вы тестируете одну конкретную функцию (exp).Мы на самом деле не знаем, идентичны ли две реализации функции exp(), которые вы тестируете, (не исключено, что одна из них лучше оптимизирована, чем другая).

Если бы вы тестировалиВ другой функции результаты могут быть совершенно другими (возможно, в большей степени соответствовать вашим ожиданиям; или нет).

Если exp() действительно является узким местом вашего фактического приложения, одна из возможностей - изучить использованиебыстрое приближение.Вот статья, которая предлагает одно такое приближение: Быстрое, компактное приближение экспоненциальной функции .

1 голос
/ 25 февраля 2012

Попробуйте включить опцию -ffast-math. Это может дать вам гораздо менее педантически правильную реализацию exp(). Тогда возникает вопрос: хотите ли вы получить потенциально неправильный ответ?

1 голос
/ 23 февраля 2012

Как уже отмечалось, вы просто сравниваете одну реализацию математической библиотеки exp( ) с другой.Если вам нужны высококачественные математические библиотеки в Linux, я бы посоветовал взглянуть на инструменты компилятора Intel (которые поставляются с отличным набором библиотек);они также доступны для OS X и Windows.

0 голосов
/ 23 февраля 2012

разница в количестве циклов процессора составляет всего 30%. Учитывая, что мы не знаем точно, какой код сгенерировал компилятор, я бы не сказал, что это абсурд. Большая часть прироста производительности с вашим новым процессором - это количество ядер, и ваш код этого не использует.

Также может быть интересно попробовать развернуть цикл. Соотношение скоростей может измениться.

int main() {
    double res0 = 0.0;        
    double res1 = 0.0;        
    double res2 = 0.0;        
    double res3 = 0.0;        
    double res4 = 0.0;        
    for(int i=1; i<200000000; i+=5) {
            res0 += exp((double) 100.0/i);
            res1 += exp((double) 100.0/(i+1));
            res2 += exp((double) 100.0/(i+2));
            res3 += exp((double) 100.0/(i+3));
            res4 += exp((double) 100.0/(i+4));
    }
    double res=res0+res1+res2+res3+res4;
    printf("%lf", res);
    return(0);
}
0 голосов
/ 23 февраля 2012

Несколько вещей, которые нужно попробовать:

  • Убедитесь, что ваш ЦП настроен на работу с полной скоростью во время эксперимента.Это может быть переключение вверх и вниз, что приводит к большим накладным расходам
  • Прикрепите тестовую программу к одному ядру, используя taskset, чтобы планировщик ОС не перенес ее вокруг
0 голосов
/ 23 февраля 2012

Вы сравниваете яблоки и апельсины, для Mac вы допускаете оптимизацию под конкретную архитектуру, а для Ubuntu - нет.Используйте -O3 -march=native на обоих, чтобы иметь справедливое сравнение.

...