pthread отлично работает, только если количество потоков мало - PullRequest
0 голосов
/ 07 января 2020

Я пытаюсь зашифровать изображение BMP, пиксель за пикселем, и я использую pthread для их параллельного шифрования.

Мой код выглядит примерно так:

struct arg_struct {
    int arg1;
    int arg2;
    ...
};

void* print_message(void* arguments) {
    struct arg_struct* args = (struct arg_struct*)arguments;

    //Encryption...

    // exit from current thread
    pthread_exit(NULL);
}

void multiThreadExample() {
    cout << "Start..." << endl;
    const int NUMBER_OF_THREADS = 50000; // number of pixels
    pthread_t thread[NUMBER_OF_THREADS];
    arg_struct arg[NUMBER_OF_THREADS];
    for (int i=0;i<NUMBER_OF_THREADS;i++) {
        arg[i].arg1 = i;
        arg[i].arg2 = ... // give values to arguments in arg_struct
        pthread_create(&thread[i], NULL, print_message, static_cast<void*>(&arg[i]));
    }

    for(int i = 0; i < NUMBER_OF_THREADS; i++) {
        pthread_join(thread[i], NULL);
    }

    cout << "Complete..." << endl;

    //streaming results to file using filebuf
}

int main() {

    multiThreadExample();

    return 0;
}

Это работает хорошо, если изображение всего 3 * 3.

Если изображение становится больше, например, 240 * 164, программа зависает ПОСЛЕ , распечатывая "Complete ..."

Через несколько минут написано Segmentation fault (core dumped).

Я не уверен, что заставляет программу зависать после того, как самая тяжелая часть (шифрование) уже завершена. Это потому, что столько потоков уже заняло все пространство моей памяти? Во время работы он занимал максимум 10G.


На самом деле я пытался сделать это БЕЗ многопоточности, и программа по-прежнему зависает.

1 Ответ

9 голосов
/ 07 января 2020

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

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

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