LINUX.ORG.RU

[CUDA] циклический здвиг вправо

 


0

0

Собственно по сабжу интересует как это сделать и возможно ли.
Да и вообще смутило, что в стандартах C/C++ нет встроенных функций для этого. Или я ошибаюсь? Поправьте меня пожалуйста!

Всем заранее спасибо за ответы.

★★★★★

*сдвиг
fixed

trex6 ★★★★★
() автор топика

#define ROR32(val,bits) (((val) >> ((bits)&0x1f)) | ((val) << (32-(bits)&0x1f)))
#define ROL32(val,bits) (((val) << ((bits)&0x1f)) | ((val) >> (32-(bits)&0x1f)))

linuxfan
()
Ответ на: комментарий от linuxfan

6 операций на языке программирования.
На ассемблере - одна операция, которая выполняется за один такт процессора. Производительность падает в 6(!) раз по сравнению с возможной.
Не очень подходит.

trex6 ★★★★★
() автор топика
Ответ на: комментарий от trex6

> На ассемблере - одна операция, которая выполняется за один такт процессора

Ключевой вопрос: на каком ассемблере? Да и про один такт процессора -- это крайне оптимистично.

kemm
()
Ответ на: комментарий от trex6

>Производительность падает в 6(!) раз по сравнению с возможной.

Во-первых, никто не мешает тебе изучить ассемблер GPU процессоров.

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

linuxfan
()
Ответ на: комментарий от kemm

Имелся ввиду ассемблек x86. Там это точно выполняется за один такт (во всяком случае так говорится в документации на Intel'овские камни).
А вот в nvidia'вском мане такой инструкции действительно не нашел.

Чтож, жаль. Просто надеялся, что я стандарты плохо знаю и на самом деле такие операции предусмотренны =)

Ладно, тогда пойдем обходными путями.

trex6 ★★★★★
() автор топика
Ответ на: комментарий от linuxfan

Возможно до конца и не понимаю - в современном мире сложно получить достаточный опыт ассемблерного программирования (особенно обучаясь в универе).
Но твои инструкции все однотактовые (я веду рассуждения для x86), rol тоже однотактовый. Если все данные уже загруженны в регистры - производительность падает в 6 раз. Конечно есть всяческие суперскалярные вычисления и т.п., но насколько они реализованны в nvidia'вских карточках я не знаю.
Спасибо большое, что постарался помочь. Просто это немного не то, что я имел ввиду. Реализацию-то накидать не сложно, интереснее другое: операция ведь довольно простая, я подозреваю, что на многих процессорах реализованна (мне так кажется). А чтоб ее быстро запрограммировать на С/С++ методов нет. Приходится велосипедить по полной...

trex6 ★★★★★
() автор топика
Ответ на: комментарий от trex6

>Но твои инструкции все однотактовые (я веду рассуждения для x86), rol тоже однотактовый.

Современные процессоры разбивают инструкции на микрооперации, некоторые из которых могут быть выполнены параллельно. Так что бывают ситуации, когда две инструкции могут быть исполнены за то же время, что и одна.

Также не стоит забывать, что x86 -- это процессоры общего назначения, а GPU -- узкопрофильное устройство. Может быть rol/ror в одну инструкцию там нет (ну да и фиг с ним), зато он может производить интерполяцию (линейную, если не ошибаюсь) на аппаратном уровне.

linuxfan
()
Ответ на: комментарий от linuxfan

>Современные процессоры разбивают инструкции на микрооперации
Конечно есть всяческие суперскалярные вычисления <- вроде бы как раз про это я и писал. (поправьте, если не прав. буду благодарен)

>Может быть rol/ror в одну инструкцию там нет

Действительно нет. Во всяком случае про них в (NVIDIA Compute PTX: Parallel Thread Execution) ничего найти не удалось.

Ладно, тему наверное можно считать закрытой, хотя если есть желание, можно еще немного пообсуждать x86 архитектуру ;-)

P.S.: Я действительно надеялся, что на самом деле в стандартах на С/С++ уже есть что-то похожее, просто я про это не знаю.

trex6 ★★★★★
() автор топика
Ответ на: комментарий от trex6

Ну хоть тут джава рулит - в ней есть <<< и >>> ;)

theos ★★★
()
Ответ на: комментарий от Legioner

>Есть странные инструкции манипуляции со строками, они совсем не однотактовые.

Ты прав, так и есть.

trex6 ★★★★★
() автор топика
Ответ на: комментарий от trex6

6 операций на языке программирования. На ассемблере - одна операция, которая выполняется за один такт процессора. Производительность падает в 6(!) раз по сравнению с возможной. Не очень подходит.

Современные компиляторы умеют делать Магию:

$ cat test.c 
#include <stdio.h>
#include <stdint.h>

static inline uint32_t ror32(uint32_t value, int shift) {
    shift &= 31;
    return (value >> shift) | (value << (32 - shift));
}

int main()
{
	unsigned int	ui;
	uint32_t	ui32;

	scanf("%u", &ui);
	ui32 = ror32((uint32_t) ui, 5);
	printf("%ju\n", (uintmax_t) ui32);
}
$ gcc -O2 -g -c test.c
$ objdump -d -M intel -S test.o 

test.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <main>:
    shift &= 31;
    return (value >> shift) | (value << (32 - shift));
}

int main()
{
   0:	48 83 ec 18          	sub    rsp,0x18
	unsigned int	ui;
	uint32_t	ui32;

	scanf("%u", &ui);
   4:	bf 00 00 00 00       	mov    edi,0x0
   9:	31 c0                	xor    eax,eax
   b:	48 8d 74 24 0c       	lea    rsi,[rsp+0xc]
  10:	e8 00 00 00 00       	call   15 <main+0x15>
	ui32 = ror32((uint32_t) ui, 5);
	printf("%ju\n", (uintmax_t) ui32);
  15:	8b 74 24 0c          	mov    esi,DWORD PTR [rsp+0xc]
  19:	bf 00 00 00 00       	mov    edi,0x0
  1e:	31 c0                	xor    eax,eax
  20:	c1 c6 1b             	rol    esi,0x1b
  23:	e8 00 00 00 00       	call   28 <main+0x28>
}
  28:	48 83 c4 18          	add    rsp,0x18
  2c:	c3                   	ret    

anonymous
()
Ответ на: комментарий от anonymous

Оптимизирующий компилятор - это хорошо. =)
Только вот насколько это все применимо к CUDA проектам. Тем более уже определились, что там rol вроде бы нет в принципе. А жаль...

trex6 ★★★★★
() автор топика
Ответ на: комментарий от kemm

>Ключевой вопрос: на каком ассемблере?

Я навскидку не припомню ни одного ассемблера (кроме совсем древних однокристаллок, типа ВЕ48 - там наличие или отсутствие оного просто не помню) без циклического сдвига.

KRoN73 ★★★★★
()
Ответ на: комментарий от linuxfan

>Если ты говоришь о том, что 6 команд в 6 раз медленней одной, ты, очевидно, не понимаешь архитектуру современных процессоров.

Ок. Для intel post-pentium можно сказать, что 12 простых инструкций в 6 раз хуже двух :)

KRoN73 ★★★★★
()
Ответ на: комментарий от anonymous

>Современные компиляторы умеют делать Магию:

Круто :) Даже грустно иногда становится, что с Си/Си++ ушёл в более суровые времена :)

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

> Я навскидку не припомню ни одного ассемблера (кроме совсем древних однокристаллок, типа ВЕ48 - там наличие или отсутствие оного просто не помню) без циклического сдвига

Ну, помимо упомянутых GPU, я не помню, чтобы в mips'е было. Может, просто не помню... 8))

kemm
()
Ответ на: комментарий от kemm

Ну, я с MIPS, как раз, не пересекался. М.б. и нету. Ну так он с рынка уже почти и ушёл ;)

KRoN73 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.