Скорость процессора и потоки в C ++ - PullRequest
3 голосов
/ 22 февраля 2012

У меня есть следующая программа на C ++:

void testSpeed(int start, int end)
{
    int temp = 0;
    for(int i = start; i < end; i++)
    {
        temp++;
    }
}  

int main() {

    using namespace boost;

    timer aTimer;

    // start two new threads that calls the "testSpeed" function

    boost::thread my_thread1(&testSpeed,         0,  500000000);
    boost::thread my_thread2(&testSpeed, 500000000, 1000000000);

    // wait for both threads to finish
    my_thread1.join();
    my_thread2.join();

    double elapsedSec =  aTimer.elapsed();
    double IOPS = 1/elapsedSec;
}

Таким образом, идея состоит в том, чтобы проверить скорость процессора в терминах целочисленных операций в секунду (IOPS).Существует 1 миллиард итераций (операций), поэтому на 1 ГГц процессоре мы должны получать около миллиарда целочисленных операций в секунду, я полагаю.

Я предполагаю, что больше потоков = больше целочисленных операций в секунду.Но чем больше потоков я пытаюсь, тем меньше операций в секунду я вижу (у меня больше ядер, чем потоков).Что может быть причиной такого поведения?Это потоки над головой?Может быть, мне стоит попробовать гораздо более длинный эксперимент, чтобы увидеть, действительно ли помогают потоки?

Спасибо!

ОБНОВЛЕНИЕ : Итак, я изменил цикл, чтобы он выполнялся 18 миллиардов раз,и объявил временную переменную.Также добавлен еще один метод testSpeed ​​с другим именем, так что теперь один поток выполняет оба метода один за другим, в то время как два потока получают каждый метод;поэтому не должно быть никаких проблем с синхронизацией и т. д. И ... по-прежнему никаких изменений в поведении!однопоточный быстрее по таймеру.Ааа!Я нашел присоску, видимо, таймер блефует.Два потока занимают половину времени, но таймер сообщает мне, что однопоточный запуск был на две секунды быстрее.Я сейчас пытаюсь понять, почему ... Спасибо всем!

Ответы [ 2 ]

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

Я почти уверен, что компилятор оптимизирует ваши циклы.Поскольку вы не отнимаете накладные расходы на создание / синхронизацию потоков, вы фактически измеряете только это.Чем больше у вас потоков, тем больше накладных расходов вы создаете и больше времени занимает.

В целом, вы можете обратиться к документации вашего ЦП и узнать о его частоте и о том, сколько тиков занимает любая данная инструкция.Проверить это самостоятельно, используя такой подход, практически невозможно и, ну, в общем, бесполезно.Это связано с такими издержками, как переключение контекста, передача выполнения с одного ЦП / ядра на другое, выгрузка планировщика, неправильное предсказание ветвлений.В реальной жизни вы также можете столкнуться с отсутствием кэша и большой задержкой шины памяти, поскольку нет программ, которые вписываются в ~ 15 регистров.Так что лучше тестируйте настоящую программу, используя хороший профилировщик.Например, новейшие процессоры могут выдавать информацию о останове процессора, промахах кэша, неправильных прогнозах веток и многом другом.Вы можете использовать хороший профилировщик, чтобы на самом деле решить, когда и как распараллеливать вашу программу.

2 голосов
/ 22 февраля 2012

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

Согласно этому документу, на многоядерном компьютере, когда количество потоков очень мало (порядка числа ядер), производительность будет увеличиваться при увеличении количества потоков, потому что теперь ядрав настоящее время полностью используются.

После этого дальнейшее увеличение числа потоков приводит к доминированию промахов, что приводит к снижению производительности.

Если количество потоков становится очень большим, так что объем кэш-памяти на поток почти становится почти нулевым, все обращения к памяти осуществляются из основной памяти.Но в то же время увеличенное количество потоков также очень эффективно маскирует увеличенную задержку доступа к памяти.На этот раз доминирует второй эффект, ведущий к увеличению производительности.

Таким образом, долина в центре - это регион с наихудшими показателями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...