Сколько блоков и потоков можно использовать на графическом процессоре CUDA [duplicate]

Быстрое исправление:

Чтобы удалить зазор под изображением, вы можете:

  • Установить свойство vertical-align изображения на vertical-align: bottom; vertical-align: top; или vertical-align: middle;
  • Установите для свойства отображения изображения значение display:block;

См. следующий код для живой демонстрации:

#vAlign img {
  vertical-align :bottom;
}
#block img{
  display:block;
}

div {border: 1px solid red;width:100px;}
img {width:100px;}

No fix:

With vertical-align:bottom; on image:

With display:block; on image:


Объяснение: почему существует пробел под изображением?

Разрыв или дополнительное пространство под изображением не является ошибкой или проблемой, это поведение по умолчанию. Основная причина заключается в том, что изображения заменяются элементами ( см. MDN и W3C ). Это позволяет им «действовать как изображение» и иметь собственные собственные размеры, соотношение сторон ... Браузеры вычисляют свое свойство отображения inline, но они придают им особое поведение, которое приближает их к элементам inline-block (так как вы

Это также означает, что:

[...] когда изображения используются во встроенном контексте форматирования с выравниванием по вертикали: базовая линия, нижняя часть изображения будет отображаться на базовой линии контейнера. ( source: MDN , focus mine )

Поскольку браузеры по умолчанию вычисляют свойство vertical-align для базовой линии, это значение по умолчанию поведение. На следующем изображении показано, где базовая линия находится по тексту:

Location of the baseline on text [/g15]

Элементы, выровненные по базовой линии, должны содержать место для дескрипторов которые простираются ниже базовой линии (например, j, p, g ...), как вы можете видеть на приведенном выше изображении. В этой конфигурации нижняя часть изображения выравнивается по базовой линии, как вы можете видеть в этом примере:

div{border:1px solid red;}
img{width:100px;height:auto;}
jpq are letters with descender

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

div {width: 100px;border: 1px solid red;}
img {width: 100px;height: auto;}

.block img{
  display:block;
}
.bottom img{
  vertical-align:bottom;
}

Default:

With display:block;

With vertical-align:bottom;

17
задан talonmies 11 March 2012 в 22:24
поделиться

1 ответ

Как вы его написали, это ядро ​​полностью последовательное. Каждый поток, запущенный для его выполнения, выполняет одну и ту же работу.

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

В примере добавления массива параллельная операция с данными -

C[k] = A[k] + B[k];

для всех k между 0 и 128 * 1024. Каждая операция добавления полностью независима и не имеет требований к порядку, и поэтому может выполняться другой нитью. Чтобы выразить это в CUDA, можно написать такое ядро ​​следующим образом:

__global__ void mAdd(float* A, float* B, float* C, int n)
{
    int k = threadIdx.x + blockIdx.x * blockDim.x;

    if (k < n)
        C[k] = A[k] + B[k];
}

[отказ от ответственности: код, написанный в браузере, не проверенный, использовать на свой страх и риск]

Здесь, внутренний и внешний цикл из серийного кода заменяются одним потоком CUDA за операцию, и я добавил проверку ограничения в коде, чтобы в случаях, когда больше потоков запущено, чем требуемые операции, переполнение буфера не может происходить. Если ядро ​​запускается следующим образом:

const int n = 128 * 1024;
int blocksize = 512; // value usually chosen by tuning and hardware constraints
int nblocks = n / nthreads; // value determine by block size and total work

madd<<<nblocks,blocksize>>>mAdd(A,B,C,n);

Затем 256 блоков, каждая из которых содержит 512 потоков, будут запущены на оборудование графического процессора, чтобы параллельно выполнять операцию добавления массива. Обратите внимание, что если размер входных данных не был выражен как хороший раунд, кратный размеру блока, количество блоков должно быть округлено до полного набора входных данных.

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

34
ответ дан talonmies 19 August 2018 в 17:30
поделиться
  • 1
    Спасибо, когти. Это действительно помогло мне понять размеры блоков и сеток. Все это чтение, которое я делал, внезапно имело смысл. – user656210 14 April 2011 в 00:53
  • 2
    int k = threadIdx.x + gridDim.x * blockDim.x; Это, безусловно, неверно? gridDim.x * blockDim.x в вашем примере всегда будет 256 * 512. Должен быть int k = threadIdx.x + blockIdx.x * blockDim.x; Я попытался отредактировать его, но был отклонен. – Ozone 1 May 2013 в 04:02
  • 3
    @Ozone: Да, это была опечатка, спасибо за это. – talonmies 1 May 2013 в 07:09
  • 4
    Предупреждение для skim-reader: nblocks = ceil (n / nthreads); // если ваши данные не делятся отлично. – ofer.sheffer 4 April 2017 в 11:01
  • 5
    @ ofer.sheffer: я написал «Обратите внимание: если размер входных данных не был выражен как хороший раунд, кратный размеру блока, количество блоков должно быть округлено до полного набора входных данных». , Разве это недостаточно ясно? – talonmies 4 April 2017 в 11:02
Другие вопросы по тегам:

Похожие вопросы: