Как кэшируется 3D текстура памяти? -- cuda пол Связанный проблема

How is 3D texture memory cached?


7
vote

проблема

русский

У меня есть приложение, в котором 96% времени проводится в 3D-интерполяции памяти текстуры чтения (красные точки на диаграмме).

Мои ядра разработаны, чтобы сделать 1000 ~ память читается на линии, которая пересекает память текстуры произвольно, нить на линию (синие линии). Эти линии плотно упакованы, очень близко друг к другу, путешествуя в практически параллельных направлениях.

Изображение показывает концепцию того, о чем я говорю. Представьте себе, что изображение - это один «ломтик» из трехмерной памяти текстуры, например, <Код> z=24 . Изображение повторяется для всех <Код> z . Введите описание изображения здесь

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

Мои вопросы

    .
  • Если у меня есть 3D текстура с линейной интерполяцией, как я могу воспользоваться большинством на местности данных? Находя соседние линии в том же блоке в 2D или соседних линиях в 3D (3D соседи или просто соседи на куски)?

  • Как "Big" - это кеш (или как я могу проверить это в спецификации)? Это загружает это, например спросил воксель и + -50 вокруг него во всех направлениях? Это напрямую связано с количеством соседних строк, которые я поставил в каждом блоке!

  • Как интерполяция применяется к кэше текстуры памяти? Имеется ли интерполяция также в кэше или тот факт, что его интерполированные сократит задержку памяти, поскольку она должна быть сделана в самой текстовой памяти?


Работа на NVIDIA TESLA K40, CUDA 7.5, если это поможет.

Английский оригинал

I have an application where 96% of the time is spent in 3D texture memory interpolation reads (red points in diagram).

My kernels are designed to do 1000~ memory reads on a line that crosses the texture memory arbitrarily, a thread per line (blue lines). This lines are densely packed, very close to each other, travelling in almost parallel directions.

The image shows the concept of what I am talking about. Imagine the image is a single "slice" from the 3D texture memory, e.g. z=24. The image is repeated for all z. enter image description here

At the moment, I am executing threads just one line after the other, but I realized that I might be able to benefit from texture memory locality if I call adjacent lines in the same block, reducing the time for memory reads.

My questions are

  • if I have 3D texture with linear interpolation, how could I benefit most from the data locality? By running adjacent lines in the same block in 2D or adjacent lines in 3D (3D neighbors or just neighbors per slice)?

  • How "big" is the cache (or how can I check this in the specs)? Does it load e.g. the asked voxel and +-50 around it in every direction? This will directly relate with the amount of neighboring lines I'd put in each block!

  • How does the interpolation applies to texture memory cache? Is the interpolation also performed in the cache, or the fact that its interpolated will reduce the memory latency because it needs to be done in the text memory itself?


Working on a NVIDIA TESLA K40, CUDA 7.5, if it helps.

</div
  
         
         

Список ответов

4
 
vote
vote
Лучший ответ
 

Как этот вопрос стареет, и никаких ответов, похоже, не существует для некоторых вопросов, которые я спросил, я предоставим ориентир ориентира, основанный на моем исследовании, здании Tigre Toolbox. Вы можете получить исходный код в github repo .

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


Особенности

Важно отметить: это Cone Beam вычисляемая томографическая приложения. Это означает, что:

    .
  • Линии более или менее равномерные распределены по изображению, накрывая большую часть этого
  • Линии более или менее параллельны соседними линиями, а также будет преимущественно всегда в одной плоскости. Например. Они всегда более или менее горизонтальные, никогда не вертикальные.
  • Образец скорости на вершине строк одинаково, что означает, что соседние линии всегда будут образены в следующую точку, очень близко друг к другу.

вся эта эта информация важна для местности памяти.

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


вопросы

Если у меня есть 3D текстура с линейной интерполяцией, как я могу воспользоваться большинством на местности данных? Бегите соседние линии в том же блоке в 2D или соседних линиях в 3D (3D соседи или просто соседи на срезе)?

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

Это эффективно для томографии означает беглый квадратный детектор пиксельных блоков. Упаковочные лучи (синие линии на исходном изображении) вместе.

Как «Big» - это кеш (или как я могу проверить это в спецификации)? Это загружает это, например спросил воксель и + -50 вокруг него в каждом направлении? Это напрямую связано с количеством соседних строк, которые я поставил в каждый блок!

В то время как невозможно сказать, эмпирически я обнаружил, что бегущие меньшие блоки лучше. Мои результаты показывают, что для изображения 512 ^ 3, с 512 ^ 2 лучами, с частотой образца ~ 2 образцов / вокселя, размер блока:

 <код> 32x32 -> [18~25] ms 16x16 -> [14~18] ms 8x8   -> [11~14] ms 4x4   -> [25~29] ms   

Размеры блоков эффективно, размер квадратных соседних лучей, которые вычисляются вместе. Например. 32x32 означает, что 1024 рентгеновские сигналы будут вычислены параллельно, рядом друг с другом на квадратном блоке 32x32. Поскольку точно такие же операции выполняются в каждой строке, это означает, что образцы принимаются около 32x32 плоскости на изображении, покрывая приблизительно индексами 32x32x1.

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

Это результаты показывает дополнительную информацию, не задающую в исходном вопросе: Что происходит без изменений образцов, касающихся скорости . Как добавляя любой <код> if условия в ядре, значительно замедляет его, способ, которым я запрограммировал ядро, запускает выборку в точке в линии, которая обеспечивается вне изображения, и останавливаться в похожий случай. Это было сделано путем создания вымышленной «сферы» вокруг изображения и всегда отбирая такую же сумму, независимо f угол между изображением и самими строками.

Если вы видите время для каждого ядра, которое я показал, вы заметили, что все они <код> [t ~sqrt(2)*t] , и я проверил, что действительно, тем более длинные времена, когда угол между линиями И изображение кратки 45 градусов, где больше образцов падают внутри изображения (текстура).

Это означает, что выборки из индекса изображения (<код> tex3d(tex, -5,-5,-5) ) является вычислительно бесплатно . Нет времени не проводить в чтении за пределами границ. Лучше прочитать много изменений, чем для проверки, если точки падают внутри изображения, поскольку <код> if if условие замедляют ядро, а отбор отбора претензий имеет нулевые расходы.

Как интерполяция применяется к кэше текстуры памяти? Имеется ли интерполяция также в кэше или тот факт, что его интерполированные снизит задержку памяти, потому что она должна быть сделана в самой текстовой памяти?

Чтобы проверить это, я пробежал тот же код, но с линейной интерполяцией (<код> cudaFilterModeLinear ) и ближайшей соседней интерполяции (<код> cudaFilterModePoint ). Как и ожидалось, улучшение скорости присутствует, когда добавляется ближайший соседние интерполяции. Для 8x8 блоков с ранее упомянутыми размерами изображения, на моем ПК:

 <код> Linear  ->  [11~14] ms Nearest ->  [ 9~10] ms   

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

 

As this question is getting old, and no answers seem to exist to some of the questions I asked, I will give a benchmark answer, based on my research building the TIGRE toolbox. You can get the source code in the Github repo.

As the answer is based in the specific application of the toolbox, computed tomography, it means that my results are not necessarily true for all applications using texture memory. Additionally, my GPU (see above) its quite a decent one, so your mileage may vary in different hardware.


The specifics

It is important to note: this is a Cone Beam Computed Tomography applications. This means that:

  • The lines are more or less uniformily distributed along the image, covering most of it
  • The lines are more or less parallel with adjacent lines, and will predominantly be always in a single plane. E.g. They always are more or less horizontal, never vertical.
  • The sample rate on top of the lines is the same, meaning that adjacent lines will always sample the next point very close to each other.

All this information is important for memory locality.

Additionally, as said in the question, 96% of the time of the kernel is memory reading, so its safe to assume that the variation of the kernel times reported are due to changes in speed of memory reading.


The questions

If I have 3D texture with linear interpolation, how could I benefit most from the data locality? By running adjacent lines in the same block in 2D or adjacent lines in 3D (3D neighbors or just neighbors per slice)?

Once one gets a bit more experienced with the texture memory sees that the straightforward answer is: run as many as possible adjacent lines together. The closer to each other the memory reads are in image index, the better.

This effectively for tomography means running square detector pixel blocks. Packing rays (blue lines in the original image) together.

How "big" is the cache (or how can I check this in the specs)? Does it load e.g. the asked voxel and +-50 around it in every direction? This will directly relate with the amount of neighboring lines I'd put in each block!

While impossible to say, empirically I found that running smaller blocks is better. My results show that for a 512^3 image, with 512^2 rays, with a sample rate of ~2 samples/voxel, the block size:

32x32 -> [18~25] ms 16x16 -> [14~18] ms 8x8   -> [11~14] ms 4x4   -> [25~29] ms 

The block sizes are effectively the size of a square adjacent rays that are computed together. E.g. 32x32 means that 1024 Xrays will be computed in parallel, adjacent to each other in a square 32x32 block. As the exact same operations are performed in each line, this means that the samples are taken about a 32x32 plane on the image, covering approximately 32x32x1 indexes.

It is predictable that at some point when reducing the size of the blocks the speed would get slow again, but this is at (at least for me) surprisingly low value. I think this hints that the memory cache loads relatively small chunks of data from the image.

This results shows an additional information not asked in the original question: what happens with out of bounds samples regarding speed. As adding any if condition to the kernel would significantly slow it down, the way I programmed the kernel is by starting sampling in a point in the line that is ensured to be out of the image, and stop in a similar case. This has been done by creating a fictional "sphere" around the image, and always sampling the same amount, independent of the angle between the image and the lines themselves.

If you see the times for each kernel that I have shown, you'd notice all of them are [t ~sqrt(2)*t], and I have checked that indeed the longer times are from when the angle between the lines and the image is multiples of 45 degrees, where more samples fall inside the image (texture).

This means that sampling out of the image index (tex3d(tex, -5,-5,-5)) is computationally free. No time is spend in reading out of bounds. Its better to read a lot of out of bounds points than to check if the points fall inside the image, as the if condition will slow the kernel and sampling out of bounds has zero cost.

How does the interpolation applies to texture memory cache? Is the interpolation also performed in the cache, or the fact that its interpolated will reduce the memory latency because it needs to be done in the text memory itself?

To test this, I ran the same code but with linear interpolation (cudaFilterModeLinear)and nearest neighbor interpolation (cudaFilterModePoint). As expected, improvement of speed is present when nearest neighbor interpolation is added. For 8x8 blocks with the previously mentioned image sizes, in my pc:

Linear  ->  [11~14] ms Nearest ->  [ 9~10] ms 

The speedup is not massive but its significant. This hints, as expected, that the time that the cache takes in interpolating the data is measurable, so one needs to be aware of it when designing applications.

</div
 
 
 
 

Связанный проблема

4  Проблема линкера с libstdc ++. SO.6 в связи с CUDA  ( Linker problem with libstdc so 6 in connection with cuda ) 
Сегодня я столкнулся с проблемой со ссылкой на мой сборник CUDA. У меня есть тестирование Debian Uptodate W / 2.6.32-3-AMD64. Я работал весь день в моем к...

2  Делайте темы в CUDA Warp Execute параллельно на многопроцессоре?  ( Do the threads in a cuda warp execute in parallel on a multiprocessor ) 
Деформация - 32 потока. Выполняется ли 32 потока параллельно в многопроцессоре? Если 32 потока не выполняются параллельно, то в деформации нет состояния рас...

0  Попытка адаптировать существующие C проекту Cuda, файлы .cu не найдены makefile  ( Trying to adapt existing c project to cuda cu files not found by makefile ) 
Я пытаюсь ускорить функцию клавиш в проекте C (не C ++) с помощью CUDA. По какой-то причине я не могу получить makefile, чтобы узнать расширение .cu, когда ...

0  CUDA 6.5: Ошибка MSB3191 Невозможно создать каталог и неразрешенный символ LNK2001  ( Cuda 6 5 error msb3191 unable to create directory and lnk2001 unresolved extern ) 
Я запускаю CUDA 6.5 на Visual Studio 2013 x64. У меня есть проект Project Bistance VC ++ с именем mylib, который связан с исполняемым исполняемым исполняемы...

0  Ошибка сегментации при использовании тяги :: Сортировать в CUDA  ( Segmentation error when using thrustsort in cuda ) 
Я пытаюсь сортировать массив объектов класса на основе его типа, передавая функцию сравнения в качестве параметра на сортировку тяги. Защита класса : <ко...

8  Нует ли NVIDIA RDMA GPudirect всегда действует только физические адреса (в физическом адресном пространстве CPU)?  ( Does the nvidia rdma gpudirect always operate only physical addresses in physic ) 
Как мы знаем: http://en.wikipedia.org/wiki/iommu#advantages < / a> Периферическая память пейджинга может быть подкреплена iommu . Периферический Исполь...

5  CUDA нахождение максимального значения в заданном массиве  ( Cuda finding the max value in given array ) 
Я пытался разработать небольшую программу CUDA для набора максимального значения в данном массиве, <код> int input_data[0...50] = 1,2,3,4,5....,50 <Код>...

-1  CUDA Array структур с массивами (AOSOA)  ( Cuda array of structs with arrays aosoa ) 
<Сильная> Примечание 4 Так что код наконец исправлен! Оказалось, что окончательная проблема заключалась в том, что я добавил размер пространства, выделенно...

5  CUDA выделение массива массивов  ( Cuda allocating array of arrays ) 
У меня есть проблемы с распределением массива массивов в CUDA. <код> <section>8 Что я не прав? ...

17  Ошибка: cuda_runtime.h: нет такого файла или каталога  ( Error cuda runtime h no such file or directory ) 
Как я могу заставить GCC посмотреть в / usr / cuda / local / включить для cuda_runtime.h? Я пытаюсь скомпилировать приложение CUDA с помощью конперпера. Я р...

3  Ошибка: COMPOSE файл './Docker-compose.yaml' недействителен, потому что: неподдерживаемый параметр конфигурации для Services.nvidia-Smi-Test: «Runtime»  ( Error the compose file docker compose yaml is invalid because unsupported ) 
Это мой docker-compose.yaml: <код> version: '2.3' services: nvidia-smi-test: runtime: nvidia image: nvidia/cuda:9.0-base environment: - NVIDIA...

0  Можно ли перекрывать дозированные FFTS с библиотекой CUDA и Cufftplanmany?  ( Is it possible to overlap batched ffts with cudas cufft library and cufftplanma ) 
Я пытаюсь распараллелизовать преобразования FFT из акустической библиотеки отпечатков пальцев, известную как ChromApprint. Он работает с помощью «разделения о...

8  CUDA без CUDA включена GPU [дубликат]  ( Cuda without cuda enabled gpu ) 
<в сторону CLASS = "S-NEWACTS S-WELTIVE__info JS-Post-New Imide MB16« Роль = «Статус»> Этот вопрос уже есть ответы здесь : ...

165  Как проверить установку CUDNN?  ( How to verify cudnn installation ) 
Я искал много мест, но все, что я получаю, это то, как установить его, а не как убедиться, что он установлен. Я могу подтвердить, что мой драйвер NVIDIA устан...

2  Гигантский график CUDA BFS (SEG.Fault)  ( Cuda bfs giant graph seg fault ) 
Я делаю тест на алгоритме BFS на CUDA (который я знаю, что имеет некоторые проблемы с синхронизацией, но это часть моей работы, чтобы все равно тестировать ег...

Связанный проблема

4  Проблема линкера с libstdc ++. SO.6 в связи с CUDA 
2  Делайте темы в CUDA Warp Execute параллельно на многопроцессоре? 
0  Попытка адаптировать существующие C проекту Cuda, файлы .cu не найдены makefile 
0  CUDA 6.5: Ошибка MSB3191 Невозможно создать каталог и неразрешенный символ LNK2001 
0  Ошибка сегментации при использовании тяги :: Сортировать в CUDA 
8  Нует ли NVIDIA RDMA GPudirect всегда действует только физические адреса (в физическом адресном пространстве CPU)? 
5  CUDA нахождение максимального значения в заданном массиве 
-1  CUDA Array структур с массивами (AOSOA) 
5  CUDA выделение массива массивов 
17  Ошибка: cuda_runtime.h: нет такого файла или каталога 
3  Ошибка: COMPOSE файл './Docker-compose.yaml' недействителен, потому что: неподдерживаемый параметр конфигурации для Services.nvidia-Smi-Test: «Runtime» 
0  Можно ли перекрывать дозированные FFTS с библиотекой CUDA и Cufftplanmany? 
8  CUDA без CUDA включена GPU [дубликат] 
165  Как проверить установку CUDNN? 
2  Гигантский график CUDA BFS (SEG.Fault)