> > Кроме того, нужно > > придумать способ лочить очередь без захвата шины (уже > в > > однопроцессорном окружении), но на мой взгляд это > довольно > > легко. > > А как? ... Саттер не так давно написал нескольно статей по > этому поводу. Но я признаться не смотрел.
Саттера не читал, но мнение имею
Вообще интуиция подсказывает, что обычный CMPXCHG (без префикса LOCK) - должен отлично сработать. Я могу ошибаться, но насколько я понимаю поток может быть вытеснен только между инструкциями, а не прямо посреди (если прерывание приходит посреди инструкции, то процессор дожидается окончания этой инструкции) - а для однопроцессорной среды этого достаточно для обеспечения атомарности. Соответственно, когда флаг, блокирующий очередь для процессора (одна очередь - один флаг) не получается "захватить" - отдаем квант чем то вроде sleep(0) или подобным и делаем спин. Огромная стоимость такой операции для ожидающего потока будет нивелироваться крайне низкой вероятностью рейса на участке из десятка инструкций (pop из односвязного списка и освобождение очереди).
-------------------
Кстати, о текущем процессоре. В Win2k3 появилась полезная функция GetCurrentProcessorNumber. Вот так выглядит версия из Win7 (в других скорее всего что то подобное):
ntdll!RtlGetCurrentProcessorNumberEx:
7787cab6 8bff mov edi,edi
7787cab8 55 push ebp
7787cab9 8bec mov ebp,esp
7787cabb 8b5508 mov edx,dword ptr [ebp+8]
7787cabe 33c0 xor eax,eax
7787cac0 668902 mov word ptr [edx],ax
7787cac3 b93b000000 mov ecx,3Bh
7787cac8 0f03c1 lsl eax,ecx
7787cacb c1e80e shr eax,0Eh
7787cace 884202 mov byte ptr [edx+2],al
7787cad1 c6420300 mov byte ptr [edx+3],0
7787cad5 5d pop ebp
7787cad6 c20400 ret 4
---
Передается туда указатель на структуру:
typedef struct _PROCESSOR_NUMBER {
WORD Group;
BYTE Number;
BYTE Reserved;
} PROCESSOR_NUMBER, *PPROCESSOR_NUMBER; ---
Так что болдом выделено конкретно получение номера процессора. Висты сейчас под рукой нет - проверить не могу, но как я уже сказал вряд ли она уходит в ядро, так что можно смело использовать эту функцию - оверхед на IPI и коллизии по идее должен быть больше. Так что можно сделать более продуктивную версию для 2k3+ с откатом к бейскейс реализации на interlocked-очереди для 2k/xp
|