Re: Коммуникация
От: jyuyjiyuijyu  
Дата: 30.04.12 00:25
Оценка: 11 (2)
Здравствуйте, Аноним, Вы писали:

А>Всем привет, есть простая проблема:


А>У меня есть 1 поток который должен передавать данные в пул других потоков, как можно сделать такую коммуникацию максимально быстро?

А>Думал сделать список и синхронизацию — но из за синхронизации — будет падать быстродействие, как решить?

А>Заранее спасибо!



в kernel32 есть поддержка lock-free списка

InitializeSListHead
InterlockedFlushSList
InterlockedPopEntrySList
InterlockedPushEntrySList
QueryDepthSList


в ntdll есть удобный механизм "много читателей один писатель"
фактически блокировка будет только при записи читать все
одновременно будут


RtlAcquireResourceExclusive
RtlAcquireResourceShared
RtlConvertExclusiveToShared
RtlConvertSharedToExclusive
RtlDeleteResource
RtlDumpResource
RtlInitializeResource
RtlReleaseResource
Коммуникация
От: Аноним  
Дата: 29.04.12 21:48
Оценка:
Всем привет, есть простая проблема:

У меня есть 1 поток который должен передавать данные в пул других потоков, как можно сделать такую коммуникацию максимально быстро?
Думал сделать список и синхронизацию — но из за синхронизации — будет падать быстродействие, как решить?

Заранее спасибо!
Re: Коммуникация
От: dilmah США  
Дата: 29.04.12 21:57
Оценка:
А>У меня есть 1 поток который должен передавать данные в пул других потоков, как можно сделать такую коммуникацию максимально быстро?
А>Думал сделать список и синхронизацию — но из за синхронизации — будет падать быстродействие, как решить?

можно уменьшить затраты на синхронизацию если группировать данные в пакеты покрупнее, и делать синхронизацию только для пакетов
Принимать решение, что пора завершить пакет -- либо если его размер превысил порог, либо если время истекшее с предыдущего пакета превысило порог.
Re: Коммуникация
От: Erop Россия  
Дата: 30.04.12 00:23
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Думал сделать список и синхронизацию — но из за синхронизации — будет падать быстродействие, как решить?


может это подойдёт?

А>Заранее спасибо!

Для "спасибо" тут есть кнопки.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Коммуникация
От: jyuyjiyuijyu  
Дата: 30.04.12 02:24
Оценка:
можно еще так правда незнаю насколько это быстро (писал в блокноте не тестил)

DWORD WINAPI ThreadPool()
{
    for (;;)
    {
        WaitForMultipleObjects(hSemaphore)
        SetEvent(hDecrease)
        RtlAcquireResourceShared()
        // pop item 
        RtlReleaseResource()
    }
}


#define MAX_AVAILABLE_ITEMS 2000 ??


DWORD WINAPI SingleWriter()
{
    for (;;)
    {
        if (NtQuerySemaphore() < MAX_AVAIL_ITEM)
        {
            // get next item
            RtlAcquireResourceExclusive()
            // push item
            RtlReleaseResource()
            ReleaseSemaphore( 1 )
        }
        else
        {
            for (;;)
            {
                WaitForSingleObject(hDecrease)                
                if (NtQuerySemaphore() < MAX_AVAIL_ITEM)
                {
                    break;
                }
            }
        }
    }
}

// create semaphore with LONG_MAX lMaximumCount 
hSemaphore = CreateSemaphore(NULL, 0, LONG_MAX, NULL)
// create auto reset event
hDecrease = CreateEvent(NULL, FALSE, FALSE, NULL)

const size_t WAIT_THREADS = 5 ??
for (int i = 0; i < WAIT_THREADS; i++)
    CreateThread(PoolThread)

CreateThread(SingleWriter)
Re[3]: Коммуникация
От: jyuyjiyuijyu  
Дата: 30.04.12 07:30
Оценка:
или даже так (в первом примере надо тоже заменить WaitForMultipleObjects на WaitForSingleObject)

DWORD WINAPI ThreadPool()
{
    for (;;)
    {
        WaitForSingleObject(hSemaphore)
        SetEvent(hDecrease)
        InterlockedPopEntrySList()
    }
}


#define MAX_AVAILABLE_ITEMS 2000 ??


DWORD WINAPI SingleWriter()
{
    for (;;)
    {
        if (NtQuerySemaphore() < MAX_AVAIL_ITEM)
        {
            GetNextItem()
            InterlockedPushEntrySList()
            ReleaseSemaphore( 1 )
        }
        else
        {
            WaitForSingleObject(hDecrease)                
        }
    }
}

// create semaphore with LONG_MAX lMaximumCount 
hSemaphore = CreateSemaphore(NULL, 0, LONG_MAX, NULL)
// create auto reset event
hDecrease = CreateEvent(NULL, FALSE, FALSE, NULL)

const size_t WAIT_THREADS = 5 ??
for (int i = 0; i < WAIT_THREADS; i++)
    CreateThread(PoolThread)

CreateThread(SingleWriter)
Re: Коммуникация
От: DogBone  
Дата: 30.04.12 16:12
Оценка:
Здравствуйте, Аноним

Если для винды то я когда-то использовал для аналогичной задачки Completion Port.

посмотри на

CreateIoCompletionPort
GetQueuedCompletionStatus
GetQueuedCompletionStatusEx
PostQueuedCompletionStatus

Это не обязятельно для IO. Хорошо работает просто при передаче данных (задач) от одного потока в пул потоков на обработку.
Re[2]: Коммуникация
От: DogBone  
Дата: 30.04.12 16:22
Оценка:
Здравствуйте, DogBone, Вы писали:

Давно это было — запамятовал — Был у меня IO

DB>Здравствуйте, Аноним


DB>Если для винды то я когда-то использовал для аналогичной задачки Completion Port.


DB>посмотри на


DB>CreateIoCompletionPort

DB>GetQueuedCompletionStatus
DB>GetQueuedCompletionStatusEx
DB>PostQueuedCompletionStatus
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.