LINUX.ORG.RU

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

> http://www.rampant.org/doors/

doors? на Linux? самые быстрые? как-то слабо верится. а ссылку на performance test? а doors есть в составе штатного RHEL4? нет? ну понятно..

// wbr

klalafuda ★☆☆
()

> Какой из IPC самый быстрый для большого объёма данных? Думаю, shared mem ?

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

Например, на Альтиковской НУМЕ есть такая штука, BTE (Block Transfer Engine) называется, которая может переносить данные минуя процессор и кэши. Делает это она в разы быстрее, чем доступ процессора к неаффинным данным.

>Можно ли разшарить уже существующюю в процессе память?

Хм, никогда не задумывался над такой задачей... Может, mmap такое может?

> ...то какой лучше пользовать ?

Идеологически верным я считаю только анонимный mmap с MEM_SHARED :-)

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

....а расшарить существующую память - вряд ли. И в mmap'е такого точно не было. Думаю получишь что-нибудь вроде SIGSEGV.

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

mmap может расшарить существующую память, но обнулит ее %) Указываем переменную, выравниваем ее по границе страницы (4кб). И делаем mmap(адрес_переменной,длина,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_FIXED|MAP_ANONYM OUS,0,0)

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

> mmap может расшарить существующую память

А из другого процесса эту память как увидеть ? Адрес через, например, сообщение передать?

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

так где-то: int x __attribute__((aligned(4096)));

mmap(&x,sizeof(int),...) fork();

и далее, изменяя переменную x в родителе, все изменения этой переменной должны быть видны в ребенке. (и наооборот)

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

> А из другого процесса эту память как увидеть ? Адрес через, например, сообщение передать?

man shm_open

// wbr

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

Chumka(*) (16.09.2006 17:30:57):

> mmap(&x,sizeof(int),...) fork();

Так память расшарится только с будущей дочкой, и то, если mmap не сглючит (он не шибко любит MAP_FIXED).

Как я понимаю, вопрос был про то, как "экспортировать" существующий кусок, чтобы он стал виден уже существующему параллельному процессу...

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

> вопрос был про то, как "экспортировать" существующий кусок, чтобы он стал виден уже существующему параллельному процессу...

Именно...

Т.к. память для према по dma маплю из драйвера, то, наверное, лучшее - mmap с MAP_SHARED из двух процессов. Хотя было бы интересно узнать как из одного процесса уже существующую память замапить в другой. Если возможно конечно...))

eraser
() автор топика

это сильно зависит от задачи и программиста в часности квалификации последнего.

на больших обьёмах данных но нечастых транзакциях - однозначно шаренная память

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

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

> если количество транзакций в секунду критический параметр

2ms - такт... и 12Мб - это для шаред как ?

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

eraser :

> 2ms - такт... и 12Мб - это для шаред как ?

Архитектура?

Двухголовый Ксеон с общей шиной? Спрак? АМД с Гипертранспортом? Итаники с ccNUMA на FatTree?

И что ты с этими данными делать собираешься?

Если обрабатывать их независимыми блоками, влезающими в L3 кыш -- одно. А если на девайс их сбрасывать -- другое.

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

Мля... Обшибся... Это 24KB за 2 ms... x86 prescott. Получаю данные по PCI пишу в файл и шарю между процессами для обработки...

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

> shm_open || sharem memory System V

Я ща делаю mmap с MAP_SHARED устройства из разных процессов. Вроде работает. А между процессами shmget, shmat - это кошерно ? Почему-то все shm_open советуют - это лучше, правильней ?

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

2eraser (*) (17.09.2006 2:15:19):

> Я ща делаю mmap с MAP_SHARED устройства из разных процессов.

Я свое мнение уже озвучил -- правильно все делаешь.

> А между процессами shmget, shmat - это кошерно ?

ИМХО нет.

> Почему-то все shm_open советуют - это лучше, правильней ?

ИМХО нет.

Долго пояснять -- сейчас не успею, поздно уже, жена не даст :)

Вкраце -- mmap с наследованием через fork() позволяет естественным образом освободить все расшаренные ресурсы после того, как алгоритм отработал свое. Все остальное требует _на_порядки_ более сложных отслеживаний в процессе построения взаимодействий -- как правило. совершенно лишних.

Die-Hard ★★★★★
()
Ответ на: комментарий от eraser

2eraser:

> x86 prescott. Получаю данные по PCI пишу в файл и шарю между процессами для обработки...

Вау! (В смысле, мне б такие проблемы :-) )

Тут шаренная память однозначно. Как я понимаю, у тебя вообще не SMP. Просто без вариантов.

Честно говоря, в одноголовом случае стОит подумать о том, чтобы все обрабатывать в одном адресном пространстве -- однозначно будет быстрее. ..

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

Ещё вопрос: Один процесс должен с максимально возможной скоростью (в смысле доставки к др. процессу) посылать короткие сообщения другому. Что лучше использовать: очереди сообшений (msgsnd...), сигналы или ещё что-то??? Повторю - главное скорость доставки сообщения, т.е. минимизировать время с момента отправки сообщения одним пр-ом до время реакции другого.

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

если сообщения короткие - то однозначно сигналы от SIGRTMIN до SIGRTMAX

совсем честно, если крайне важна скорость, то зря вы на процессах зашорились - внутри одного процесса, но на разных тредах данные передаются ГООРАЗДО БЫСТРЕЕ. и менее геморойно кстати :)

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

MKuznetsov :

> если сообщения короткие - то однозначно сигналы от SIGRTMIN до SIGRTMAX

Почему?

Они ж туда-сюда в ядро сходить должны. А если асинхронность не нужна, то все можно в юзерспейсе сделать.

Еще -- я как-то сравнивал скорость засыпания/просыпания процесса на RT сигналах и на SySV семафорах -- семафоры оказались в разы быстрее. Может, конечно, сравнивал некорректно...

> внутри одного процесса, но на разных тредах данные передаются ГООРАЗДО БЫСТРЕЕ.

Можно подробнее? Чем шаренная между процессами память отличается от общей памяти трэдов?

Die-Hard ★★★★★
()
Ответ на: комментарий от eraser

eraser (*) (17.09.2006 15:34:46):

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

Попробуй!

Мне кажется, победит проверка расшаренной волатильной переменной. Если процессор только один, то никаких проблем с барьерами не будет. Для SMP все, что надо, можно взять из исходников ядра.

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

>> если сообщения короткие - то однозначно сигналы от SIGRTMIN до SIGRTMAX

>Почему?

по постановке задачи :) для передачи сообщений между процессами в классике UNIX можно использовать 1) сигналы - если надо шустро оповещать о событии, весь механизм передачи и приёма уже реализован им надо только воспользоваться 2) сообщения SYSV - если надо соблюсти некий протокол обмена, механизм передачи реализован, надо продумать и реализовать последовательность и форматы обмена 3) шаренную память и семафоры - если надо передавать значительные объёмы данных - есть только механизм синхронизации и разделения памяти а интерфейс обмена придётся думать и реализовывать самому. Зато просторр - можно например передавать видеопоток и синхонизовать по опорным кадрам 4) пайпы и fifo - если передаётся длинная 'колбаса' данных в пределах одного хоста 5) сокеты - если нет гарантии что приёмник и передатчик на одном хосте. 6) прочее в зависимости от цели.

как я понял поставленный вопрос, автору надо чтобы процессы обменивались данными о асинхронно-происходящих событиях. Для этого и сделанны сигналы. Можно конечно реализовать то-же самое и на семафорах, но накладные расходы на эту реализацию IMHO чрезмерны.

> Можно подробнее? Чем шаренная между процессами память отличается от общей памяти трэдов?

нет необходимости её синхронизовать для гарантий однозначности, мутексы внутри тредов работают быстрее чем семафоры - да и вообще меньше гемороя и накладных расходов.

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

>> Можно подробнее? Чем шаренная между процессами память отличается от общей памяти трэдов?

>нет необходимости её синхронизовать для гарантий однозначности, мутексы внутри тредов работают быстрее чем семафоры - да и вообще меньше гемороя и накладных расходов.

Die-Hard для этих целей обычно пользует спинлоки на быстродействие которых покачто нареканий небыло

а вообще гарантированно получить 2 мс необходимые автору без настроек шедуллера - никак. а то ещё чего добро RT-патчи накатывать придётся или вообще на QNX переползать

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

> а вообще гарантированно получить 2 мс необходимые автору

Нет... 2 mc обеспечивает внешнее устройство (обращается с этим периодом), а мне надо за это время просто всосать и обработать данные .

eraser
() автор топика
Ответ на: комментарий от Die-Hard

> Как я понимаю, вопрос был про то, как "экспортировать" существующий кусок, чтобы он стал виден уже существующему параллельному процессу...

в качестве разделяемой памяти можно использовать mmap-нутые файлы. В этом случае можно передавать дескриптор открытого файла в другой процесс. Файл можно создавать в памяти.

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

Sorcerer :

> в качестве разделяемой памяти можно использовать mmap-нутые файлы. В этом случае можно передавать дескриптор открытого файла в другой процесс. Файл можно создавать в памяти.

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

Die-Hard ★★★★★
()
Ответ на: комментарий от cvv

cvv

> Die-Hard для этих целей обычно пользует спинлоки на быстродействие которых покачто нареканий небыло

:-)

Не делайте так, если до конца не понимаете, что делаете!

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

Die-Hard ★★★★★
()
Ответ на: комментарий от MKuznetsov

MKuznetsov(*) (17.09.2006 19:35:59):

> ...для передачи сообщений между процессами в классике UNIX можно использовать ...

Да, если ограничиться готовыми переносимыми решениями.

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

> Для этого и сделанны сигналы. Можно конечно реализовать то-же самое и на семафорах, но накладные расходы на эту реализацию IMHO чрезмерны.

Я уже писАл, что как-то сравнивал тормознутость sigsuspend() на RT сигналах с SySV семафорами (ядро 2.4 было), так победили (к моему удивлению) семафоры, причем с большим отрывом.

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

>> Можно подробнее? Чем шаренная между процессами память отличается от общей памяти трэдов?

> нет необходимости её синхронизовать для гарантий однозначности,

Ну, тут я не согласен. Синхронизация требуется точно также.

Другое дело, что pthread предоставляет все необходимые примитивы на достаточно высоком уровне, не надо изголяться с волатильными переменными и (непереносимыми вообще-то) барьерами и атомарными операциями.

> мутексы внутри тредов работают быстрее чем семафоры - да и вообще меньше гемороя и накладных расходов.

Да, за счет того, что они не сразу в ядро уходят.

Но, заметим, что, начиная с 2.5.40 (и даже чуть раньше) в Линуксе доступен futex (кстати, как я понимаю, NPTLные мутексы именно на нем построены -- хотя, не уверен). Да и самому некое подобие для конкретной архитектуры сделать несложно, я в 2.4 на Итаниках под icc (замечу, там встроенный ассемблер не работает!) делал спинлок + SySV семафор -- очень шустро работает!

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

> Низкоуровневая отсебятина под конкретную платформу обычно бывает быстрее.

А, если можно, примерчик "Низкоуровневой отсебятины" на тему максимально быстрого обмена сообщениями между процессами. Я вот делаю так
volatile uint *sh_mem - указатель на шареную память размером,например 256 32-битных слов.

1-ый процесс отправитель
*(sh_mem + 25) = 0xAABBCCDD; - посылаю сигнал
.......................
2-ой процесс получатель
while(*(sh_mem + 25)!=0xAABBCCDD) {} *(shm_i + 25) = 0; - принял
........................
Вроде работает...
На сколько это правильно?? Ну и примерчик может еще как правильней :)

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

eraser (18.09.2006 20:41:38):

Да, примерно так.

Только в учти, что при наличии нескольких процессоров нужен барьер.
Например, 

На одном процессоре:

*sh_mem = 0x00000000;
 . . .
*sh_mem = 0xFFFFFFFF;
*(sh_mem + 25) = 0xAABBCCDD;

На втором:

while(*(sh_mem + 25)!=0xAABBCCDD) {} *(shm_i + 25) = 0;

*sh_mem == ???

Не факт, что 0xFFFFFFFF: x86 мог переупорядочить
*sh_mem = 0xFFFFFFFF;
и
*(sh_mem + 25) = 0xAABBCCDD; 

Если процессор только один, таких проблем нет, но цикл
while(*(sh_mem + 25)!=0xAABBCCDD) {}

сожрет бОльшую часть CPU.

Иногда делают так:

while(*(sh_mem + 25)!=0xAABBCCDD) {
   sched_yield();
}

но sched_yield(); не всегда работает, как ожидается.

Еще способ -- покрутиться в цикле неск. раз, после чего заснуть на
семафоре или sigsuspend(), выставив флажок в шаренной памяти (если
флаг стоит, первый процесс его потом разбудит). Конечно, это дольше.

Можно футекс задействовать, тогда вообще проблем не будет, ни с
барьерами, ни с прожорливостью busywork ожидания. Я сам ни разу не
пробовал, как-то пока не совсем понятно, как им пользоваться:
man futex ваньку показывает, а примеры у Rusty

ftp://ftp.nl.kernel.org/pub/linux/kernel/people/rusty/

маловразумительны. Надо посмотреть исходники NPTL...

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

Насчет барьеров на SMP:

Сейчас погонял библиотеку http://www.hpl.hp.com/research/linux/atomic_ops/ на четвертом Пеньке, Оптероне и Итаниуме под gcc и icc и посмотрел, во что компилится store с release семантикой (то самое, что тебе надо).

Оказалось, на Итанике gcc компилит в последовательность mf addl (то есть явно ставит барьер и прибавляет 0), icc -- в st4.rel ( т.е. store с release барьером).

На Пеньке и на Оптероне никаких барьеров не генерилось! За исключением __asm__ __volatile__("" : : : "memory"); ничего не происходило.

То есть, на x86 барьеры тут вообще не нужны, если библиотека не врет.

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

Понятно.Спасибо. Вот возникла проблема: Есть 2 компа - отличаются не сильно: i845 vs i865G, 0.5GB vs 1GB, 2.6Ghz vs 3.0 GHz соответственно, веники одинаковые.

Запускаю свои 2 процесса на обоих компах - пр-с сендер в обоих случаях работает нормально. Процесс приемник вылетая из while() (получив сигнал) должен записать данные на hdd write(...). Поток данных ~10-12MB/s. На более мощном компе - все ОК. А на другом процесс приемник начинает подтормаживать, скорее всего на write (больше негде просто). И вот вопрос - почему? Где порыть можно ??? Ведь компы практически одинаковы, поток данных небольшой, дистр Gentoo - сервисов поминимуму, ядро 2.6.17-r8, udma врублено, hdparm на обоих компах показывает 60-65 MB/s.

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

Извини, тема со страницы ушла, я сразу не отвечаю...

Не знаю... Ты хоть yeld() в цикле делаешь? Без этого, увы, тормоза будут непредсказуемые...

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