2013-05-05 2 views
1

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

Для того, чтобы начать работу с устройством, нулевой нить каждого блока должен рассчитать рекуррентное отношение от константы C0 до CW, где W= #warp - 1.

Концептуально это выглядит следующим образом:

if(threadId.x ==0) { 
    for(x=1;x<#warps;x++) { 
     C[x] = calc_recur(C[x-1]); 
    } 
} 
syncthreads(); 

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

Это будет выглядеть примерно так:

for(x=1;x<#warps;x++) { 
    if(threadId.x ==0) { 
     C[x] = calc_recur(C[x-1]); 
    } 
    if(x < warpId) { 
     partial_syncthreads(x); 
    } 
} 

где partial_syncthreads будет синхронизировать все потоки, которые принадлежат к деформации большей, чем х.

Есть ли какой-либо алгоритм, который бы включил это?

+0

Сначала: Почему вы хотите это сделать? 'syncthreads()' только гарантирует, что все потоки завершены с их предыдущей работой. Я не вижу причины, почему вы хотите синхронизировать их в каждом цикле. Второй момент: возможно, вы смешиваете термины 'block' и' warp'? – Stefan

+0

Почему я хочу это сделать: если возможно, это создаст импровизированный конвейер работы, позволяя основанию начать свою работу раньше, он также завершит работу раньше, только позже будет заполнен другой работой. Поскольку моя работа над каждым рабочим блоком сильно использует произвольный доступ, я запрашиваю способ для многих cachlines, поэтому для того, чтобы выполнить некоторую работу раньше, можно было бы снять некоторое давление в шине памяти. Причина, по которой я должен их синхронизировать, заключается в том, что они не могут убежать, прежде чем рассчитывается их рабочий блок. Нет, нити в деформации меньше x имеют рассчитанный рабочий блок. –

+0

Хорошо. Японял твою точку зрения. Безслое, я думаю, вы должны заменить термин «синхронизация» (который только гарантирует, что каждый поток находится в точке вызова этой функции) с чем-то вроде «release». Что мешает вам остановить ваше ядро, вычисляя 'C [x]' в маленьком ядре, а затем снова запуская большее ядро ​​(или то, что вы хотите сделать дальше)? Это освободит все ненужные потоки, пока вы не запустите следующее ядро. – Stefan

ответ

1

Я не совсем уверен, но я сомневаюсь, что есть способ уменьшить количество потоков во время работы ядра.

Из-за этого, я хотел бы предложить, чтобы

(1) оставить его, как есть. Синхронизация потоков на данный момент не имеет смысла.

(2) Разделить ядро ​​на несколько ядер. Таким образом, ваш отображаемый код рассчитывается меньшим количеством потоков. Но с помощью этого метода у вас не будет доступа к общей памяти.

(3) выполнить расчет на хосте. Поскольку это очень последовательная реализация, это может быть более быстрым способом. Здесь вы должны быть уверены, что ваша функция calc_recur() достаточно дорога, что передача на хост не отрицает преимущества скорости.

Смежные вопросы