OpenMP: получить общее количество запущенных потоков - PullRequest
12 голосов
/ 16 января 2011

Мне нужно знать общее количество потоков, созданных моим приложением через OpenMP.К сожалению, функция omp_get_num_threads() здесь не работает, так как она выдает только количество потоков в текущей команде.

Однако мой код выполняется рекурсивно (в основном, разделяй и властвуй) иЯ хочу порождать новые потоки, пока есть еще незанятые процессоры, но не более.

Есть ли способ обойти ограничения omp_get_num_threads и получить общее число работающие потоки?

Если требуется больше подробностей, рассмотрите следующий псевдокод, который довольно близко моделирует мой рабочий процесс:

function divide_and_conquer(Job job, int total_num_threads):
  if job.is_leaf(): # Recurrence base case.
    job.process()
    return

  left, right = job.divide()

  current_num_threads = omp_get_num_threads()
  if current_num_threads < total_num_threads: # (1)
    #pragma omp parallel num_threads(2)
      #pragma omp section
        divide_and_conquer(left, total_num_threads)
      #pragma omp section
        divide_and_conquer(right, total_num_threads)

  else:
    divide_and_conquer(left, total_num_threads)
    divide_and_conquer(right, total_num_threads)

  job = merge(left, right)

Если я вызываю этот код со значением total_num_threads, равным 4условный аннотированный (1) будет всегда оценен в true (потому что каждая команда потока будет содержать не более двух потоков) и, следовательно, код всегда будет порождать два новых потока, независимо от того, сколько потоковуже работает на более высоком уровне.

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

Ответы [ 3 ]

4 голосов
/ 16 января 2011

Я думаю, что нет такой рутины, по крайней мере, в OpenMP 3;и если бы это было так, я не уверен, что это помогло бы, поскольку между подсчетом количества нитей и разветвлением очевидно огромное состояние гонки.Вы можете в конечном итоге перебросить целевое число потоков почти в 2 раза, если все увидят, что есть место для одного оставшегося потока, а затем все порождают поток.

Если это действительно структура вашей программы, хотяи вы просто хотите ограничить общее количество потоков, есть опции (все это OpenMP 3.0):

  1. Используйте переменную среды OMP_THREAD_LIMIT, чтобы ограничить общее количество потоков OpenMP
  2. Используйте OMP_MAX_ACTIVE_LEVELS, или omp_set_max_active_levels(), или протестируйте против omp_get_level(), чтобы ограничить, насколько глубоко вложены ваши потоки;если вам нужно только 16 потоков, ограничьте до 4 уровней вложенности
  3. Если вы хотите более точный контроль, чем полномочия двух, вы можете использовать omp_get_level(), чтобы найти свой уровень, и вызвать omp_get_ancestor_thread_num(int level) на разных уровнях, чтобы найтииз какого потока был ваш родитель, дедушка и т. д. и из этого (используя эту простую разметку влево-вправо) определить глобальный идентификатор потока.(Я думаю, что в этом случае это будет что-то вроде 101 l = 0..L-1 a l 2 Ll , где l - номер уровня, начинающийся с0 и a - номер нити предка на этом уровне).Это позволило бы (скажем) разрешить потоки 0-3 для ветвления, но не 4-7, так что в итоге вы получите 12, а не 16 потоков.Я думаю, что это работает только в такой обычной ситуации;если каждый родительский поток разветвляется разным количеством дочерних потоков, я не думаю, что вы могли бы определить уникальный глобальный идентификатор потока, потому что похоже, что вы можете запрашивать только своих прямых предков.
2 голосов
/ 17 января 2011

Код, который вы показали, имеет проблему в том, что «раздел omp» должен находиться в пределах лексической области «раздел omp». Я предполагаю, что вы имели в виду «параллельная секция omp» как «параллельная секция omp». Другой способ сделать это - использовать «задачу omp», и тогда вам не нужно вести подсчет количества потоков. Вы просто назначаете потоки параллельной области и позволяете реализации OpenMP назначать задачи потокам.

0 голосов
/ 16 января 2011

Имея в виду, что вы знаете точное количество создаваемых потоков, самое простое решение, которое я придумаю, - это сохранить свой собственный счетчик потоков.

Помните, что я полностью в неведении относительно OpenMP, поскольку я 'я никогда не использовал его.

...