Re[9]: Изобретен класс что-то типа Mutex'a.
От: Алекс Россия http://wise-orm.com
Дата: 01.08.02 04:44
Оценка:
Здравствуйте Alex Smirnov, Вы писали:

[]

AS>а ты её обьяви как volatile...компилятор её в регистры и не будет запихивать.


объясняю популярно!
Когда ты сравниваешь ResCount с нулем компилятор генерит примерно такой код:
cmp ResCount,0    ;1
jnz not_zero

или
mov eax,ResCount  ;2
or eax,eax
jnz not_zero

При вызове функции будет примерно следующая картина:
push 0
push ResCount
call InterlockedExchangeAdd
or eax,eax
jnz not_zero


Панимаешь? И volatile здесь не при чем.
Re[10]: Изобретен класс что-то типа Mutex'a.
От: Alex Smirnov Россия  
Дата: 01.08.02 06:35
Оценка:
Чего напрасно спорить...Посмотри на прототип:
LONG InterlockedExchangeAdd (
  LPLONG volatile Addend,  // addend
  LONG Value               // increment value
);

Кстати и все другие процы этого типа...

Панимаешь!
Alex
Re[11]: Изобретен класс что-то типа Mutex'a.
От: Алекс Россия http://wise-orm.com
Дата: 01.08.02 06:46
Оценка:
Здравствуйте Alex Smirnov, Вы писали:

AS>Чего напрасно спорить...Посмотри на прототип:


ну посмотрел и че?

AS>Кстати и все другие процы этого типа...


???

AS>Панимаешь!


что ты мне хочешь объяснить?
Re[12]: Изобретен класс что-то типа Mutex'a.
От: Alex Smirnov Россия  
Дата: 01.08.02 07:02
Оценка:
Здравствуйте Алекс, Вы писали:

А>Здравствуйте Alex Smirnov, Вы писали:


AS>>Чего напрасно спорить...Посмотри на прототип:


А>ну посмотрел и че?


AS>>Кстати и все другие процы этого типа...


А>???


AS>>Панимаешь!


А>что ты мне хочешь объяснить?


ну раз в прототипе тебе говорят что принимаемый параметр volatile LONG*
, так и обьявляй её именно так!!! И вызов её немного отличается от твоего!
push 0
mov eax,dword ptr [this]
push eax
call dword ptr [__imp__InterlockedExchangeAdd@8 (42E27Ch)]
При учете того что:
class MyClass
{
volatile LONG lResCount;
};
и вызове: InterlockedExchangeAdd( &lResCount, 0);

Догоняешь суть???
Alex
Re: Изобретен класс что-то типа Mutex'a.
От: konst  
Дата: 01.08.02 07:18
Оценка:
Здравствуйте BlackBox, Вы писали:

BB>Привет всем!


BB> Вот написал маленький класс и думаю не изобрел ли я велосипед (в который раз... )


В МСДН-е есть какой-то "улучшенный мьютекс", отикс (optix), кажется, они его назвали, может там чего полезного для твоего класса окажется.

BB>Принимается любая критика по поводу кода.


Твой код и без меня накомментировали...Да и так пойдёт, раз работает!
Мне вот только очень интересно назначение этого класса, можешь как-нибудь попроще применение объяснить, может, мне или ещё кому и пригодится?
Re[13]: Изобретен класс что-то типа Mutex'a.
От: Алекс Россия http://wise-orm.com
Дата: 01.08.02 07:21
Оценка:
Здравствуйте Alex Smirnov, Вы писали:

[]

AS>ну раз в прототипе тебе говорят что принимаемый параметр volatile LONG*

AS>, так и обьявляй её именно так!!! И вызов её немного отличается от твоего!
AS> push 0
AS> mov eax,dword ptr [this]
AS> push eax
AS> call dword ptr [__imp__InterlockedExchangeAdd@8 (42E27Ch)]
AS> При учете того что:
AS> class MyClass
AS> {
AS> volatile LONG lResCount;
AS> };
AS> и вызове: InterlockedExchangeAdd( &lResCount, 0);

AS>Догоняешь суть???


нет
из предыдущего сообщения
что ты мне хочешь объяснить?
Re[14]: Изобретен класс что-то типа Mutex'a.
От: Alex Smirnov Россия  
Дата: 01.08.02 07:28
Оценка:
Здравствуйте Алекс, Вы писали:

А>Здравствуйте Alex Smirnov, Вы писали:


А>[]


AS>>ну раз в прототипе тебе говорят что принимаемый параметр volatile LONG*

AS>>, так и обьявляй её именно так!!! И вызов её немного отличается от твоего!
AS>> push 0
AS>> mov eax,dword ptr [this]
AS>> push eax
AS>> call dword ptr [__imp__InterlockedExchangeAdd@8 (42E27Ch)]
AS>> При учете того что:
AS>> class MyClass
AS>> {
AS>> volatile LONG lResCount;
AS>> };
AS>> и вызове: InterlockedExchangeAdd( &lResCount, 0);

AS>>Догоняешь суть???


А>нет

А>из предыдущего сообщения
А>что ты мне хочешь объяснить?

Твой код:
push 0
push ResCount
call InterlockedExchangeAdd


Мой код:
push 0
mov         eax,dword ptr [this] ; Запихивание адреса переменной а не значения!
push eax
call InterlockedExchangeAdd


А теперь?
Alex
Re[2]: Изобретен класс что-то типа Mutex'a.
От: BlackBox Россия ---
Дата: 01.08.02 07:31
Оценка:
Здравствуйте konst, Вы писали:

K>В МСДН-е есть какой-то "улучшенный мьютекс", отикс (optix), кажется, они его назвали, может там чего полезного для твоего класса окажется.

Я про этот optix у Рихтера видел. Если не ошибаюсь это не сколько не то, что мне надо было.

K>Мне вот только очень интересно назначение этого класса, можешь как-нибудь попроще применение объяснить, может, мне или ещё кому и пригодится?

Я его делал для синхронизации потоков.
Мне необходимо было 2 события:

Если не понятно могу кусочек кода привести:
  for (;;)
  {
    DWORD dw = 0;
    dw = WaitForSingleObject(BlackMutex.GetOpened(), INFINITE);
    if (dw == WAIT_OBJECT_0)
    {
      if (close) break;
      mylog->write("// - new session -----------");
      dw = WaitForSingleObject(BlackMutex.GetEmpty(), INFINITE);
      switch(dw)
      {
        case WAIT_OBJECT_0:
        {
          if (close) return 0;
          mylog->write("// - end of session -----------");
          break;
        }
        case WAIT_FAILED:
        {
          mylog->write("// - nothing to plane ------------");
          break;
        }
        default:
        {
          mylog->write("in animate thread error occured");
          break;
        }
      }
    }
    else
    {
      mylog->write("critical error in animate thread.");
    }
  }
  return 0;


Правда код не идеален
Re[3]: Изобретен класс что-то типа Mutex'a.
От: Alex Smirnov Россия  
Дата: 01.08.02 07:53
Оценка: 9 (1)
Здравствуйте BlackBox, Вы писали:

BB>Здравствуйте konst, Вы писали:


K>>В МСДН-е есть какой-то "улучшенный мьютекс", отикс (optix), кажется, они его назвали, может там чего полезного для твоего класса окажется.

BB> Я про этот optix у Рихтера видел. Если не ошибаюсь это не сколько не то, что мне надо было.

K>>Мне вот только очень интересно назначение этого класса, можешь как-нибудь попроще применение объяснить, может, мне или ещё кому и пригодится?

BB> Я его делал для синхронизации потоков.
BB> Мне необходимо было 2 события:
BB>
BB>Если не понятно могу кусочек кода привести:

BB>
BB>  for (;;)
BB>  {
BB>    DWORD dw = 0;
BB>    dw = WaitForSingleObject(BlackMutex.GetOpened(), INFINITE);
BB>    if (dw == WAIT_OBJECT_0)
BB>    {
BB>      if (close) break;
BB>      mylog->write("// - new session -----------");
BB>      dw = WaitForSingleObject(BlackMutex.GetEmpty(), INFINITE);
BB>      switch(dw)
BB>      {
BB>        case WAIT_OBJECT_0:
BB>        {
BB>          if (close) return 0;
BB>          mylog->write("// - end of session -----------");
BB>          break;
BB>        }
BB>        case WAIT_FAILED:
BB>        {
BB>          mylog->write("// - nothing to plane ------------");
BB>          break;
BB>        }
BB>        default:
BB>        {
BB>          mylog->write("in animate thread error occured");
BB>          break;
BB>        }
BB>      }
BB>    }
BB>    else
BB>    {
BB>      mylog->write("critical error in animate thread.");
BB>    }
BB>  }
BB>  return 0;

BB>


BB>Правда код не идеален


Тады так в классе и напиши:
 BOOL  IsOpened( )
 {
    return WaitForSingleObject( hEvents[1], INFINITY) == WAIT_OBJECT_0;
 }

 BOOL  IsClosed( )
 {
    return WaitForSingleObject( hEvents[0], INFINITY) == WAIT_OBJECT_0;
 }


и в коде:
  for (;;)
  {
    if(BlackMutex.IsOpened())
    {
      if (close) break;
      mylog->write("// - new session -----------");
      if(BlackMutex.IsClosed())
      {
          if (close) return 0;
          mylog->write("// - end of session -----------");
      }
      else mylog->write("in animate thread error occured");
    }
    else mylog->write("critical error in animate thread.");
  }


Вроде и короче будет
Alex
Re[15]: Изобретен класс что-то типа Mutex'a.
От: Алекс Россия http://wise-orm.com
Дата: 01.08.02 08:01
Оценка:
Здравствуйте Alex Smirnov, Вы писали:

хъ

AS>Твой код:

AS>
AS>push 0
AS>push ResCount
AS>call InterlockedExchangeAdd
AS>


AS>Мой код:

AS>
AS>push 0
AS>mov         eax,dword ptr [this] ; Запихивание адреса переменной а не значения!
AS>push eax
AS>call InterlockedExchangeAdd
AS>


AS>А теперь?


что теперь?
При чем здесь адрес переменной. Повторяю еще раз. Для чтения переменной не нужно пользоваться объектами синхронизации или функциями наподобие InterlockedExchangeAdd. Это не эффективно, не естественно и не необходимо.
Если ты этого не понимаешь, то я пас. Больше овечать тебе не буду и прикратим этот флейм. Видит бог, IT и еже с ним , что я предпринимал все попытки объяснить уважаемому господину Смирнову неэффективность кода, все видели как я старался, однако, к сожалению, это не помогло.
Больше я отвечать ему не буду.
Re[4]: Изобретен класс что-то типа Mutex'a.
От: BlackBox Россия ---
Дата: 01.08.02 08:01
Оценка:
Здравствуйте Alex Smirnov, Вы писали:

AS>Тады так в классе и напиши:

AS>
AS> BOOL  IsOpened( )
AS> {
AS>    return WaitForSingleObject( hEvents[1], INFINITY) == WAIT_OBJECT_0;
AS> }

AS> BOOL  IsClosed( )
AS> {
AS>    return WaitForSingleObject( hEvents[0], INFINITY) == WAIT_OBJECT_0;
AS> }
AS>


Спасибо!!!
Вопрос — возвращать BOOL обязательно? А другой тип нельзя?
Re[16]: Изобретен класс что-то типа Mutex'a.
От: BlackBox Россия ---
Дата: 01.08.02 08:05
Оценка:
Здравствуйте Алекс, Вы писали:

Для чтения переменной не нужно пользоваться объектами синхронизации или функциями наподобие InterlockedExchangeAdd. Это не эффективно, не естественно и не необходимо.

То есть пользоваться этими функциями имеет смысл только при изменении переменной?

p.s. я только начал осваивать многопоточное программирование ...
Re[5]: Изобретен класс что-то типа Mutex'a.
От: Alex Smirnov Россия  
Дата: 01.08.02 08:10
Оценка:
Здравствуйте BlackBox, Вы писали:

BB>Здравствуйте Alex Smirnov, Вы писали:


AS>>Тады так в классе и напиши:

AS>>
AS>> BOOL  IsOpened( )
AS>> {
AS>>    return WaitForSingleObject( hEvents[1], INFINITY) == WAIT_OBJECT_0;
AS>> }

AS>> BOOL  IsClosed( )
AS>> {
AS>>    return WaitForSingleObject( hEvents[0], INFINITY) == WAIT_OBJECT_0;
AS>> }
AS>>


BB>Спасибо!!!

BB>Вопрос — возвращать BOOL обязательно? А другой тип нельзя?

Кнчно мжно! А смысл? Раз стоит INFINITY, то вроде всего два выхода:
Сработал эвент / Ошибка ожидания
Alex
Re[16]: Изобретен класс что-то типа Mutex'a.
От: Alex Smirnov Россия  
Дата: 01.08.02 08:27
Оценка:
Здравствуйте Алекс, Вы писали:

А>что теперь?

А>При чем здесь адрес переменной. Повторяю еще раз. Для чтения переменной не нужно пользоваться объектами синхронизации или функциями наподобие InterlockedExchangeAdd. Это не эффективно, не естественно и не необходимо.
А>Если ты этого не понимаешь, то я пас. Больше овечать тебе не буду и прикратим этот флейм. Видит бог, IT и еже с ним , что я предпринимал все попытки объяснить уважаемому господину Смирнову неэффективность кода, все видели как я старался, однако, к сожалению, это не помогло.
А>Больше я отвечать ему не буду.

Да Блин!
Всё понятно про краткость получаемого кода! Только!
Если человек хочет использовать безопасный интерфейс изменения
счетчиков предоставленный производителем системы (OS),
то очень глупо предлогать на это плевать !
ГОСПОДИН АЛЕКС!
И насчет этой нити — действительно бесмысленно её продолжать!
Alex
Re[17]: Изобретен класс что-то типа Mutex'a.
От: achp  
Дата: 01.08.02 09:30
Оценка:
Здравствуйте Alex Smirnov, Вы писали:

AS>Здравствуйте Алекс, Вы писали:


А>>что теперь?

А>>При чем здесь адрес переменной. Повторяю еще раз. Для чтения переменной не нужно пользоваться объектами синхронизации или функциями наподобие InterlockedExchangeAdd. Это не эффективно, не естественно и не необходимо.
А>>Если ты этого не понимаешь, то я пас. Больше овечать тебе не буду и прикратим этот флейм. Видит бог, IT и еже с ним , что я предпринимал все попытки объяснить уважаемому господину Смирнову неэффективность кода, все видели как я старался, однако, к сожалению, это не помогло.
А>>Больше я отвечать ему не буду.

AS>Да Блин!

AS>Всё понятно про краткость получаемого кода! Только!
AS>Если человек хочет использовать безопасный интерфейс изменения
AS>счетчиков предоставленный производителем системы (OS),
AS>то очень глупо предлогать на это плевать !
AS>ГОСПОДИН АЛЕКС!
AS>И насчет этой нити — действительно бесмысленно её продолжать!

Читаем MSDN:

Simple reads and writes to properly-aligned 32-bit variables are atomic. In other words, when one thread is updating a 32-bit variable, you will not end up with only one portion of the variable updated; all 32 bits are updated in an atomic fashion. However, access is not guaranteed to be synchronized. If two threads are reading and writing from the same variable, you cannot determine if one thread will perform its read operation before the other performs its write operation.

Таким образом, приходим к выводу, что использование InterlockedExchangeAdd и т. п. для чтения значения 32-битного значения правильно выровненной переменной излишне. (Хотя для того, чтобы просто обозначить потенциальную проблему, например, на случай изменения типа на 64-битный, я бы написал функцию-обертку.)

InterlockedExchangeAdd тратит безумно много времени на такую простую операцию.

Кроме того, эта функция по-прежнему не решает проблем синхронизации. Т. е. если вообще возник такой вопрос — насчет считывания значения атомарным образом, — то значит, в этот же момент кто-то может в эту же переменную писать, а тогда встает следующий вопрос: а что мы считаем таким вот расчудесным-распрекрасным супер-атомарным образом? То что, может быть, кто-то когда-то как-то туда запишет? Что-то тут не так.
Re[18]: Изобретен класс что-то типа Mutex'a.
От: Alex Smirnov Россия  
Дата: 01.08.02 09:51
Оценка:
Здравствуйте achp, Вы писали:

Вот вроде и умный человек сюда заглянул...
Вот посоветуйте, как лучше поступать? Доверять Господину Алекс-у, или доверять мелкософту...Вот МСДН:

Synchronization and Multiprocessor Issues
Applications may encounter problems when run on multiprocessor systems due to assumptions they make which are valid only on single-processor systems.

Thread Priorities
Consider a program with two threads, one with a higher priority than the other. On a single-processor system, the higher priority thread will not relinquish control to the lower priority thread because the scheduler gives preference to higher priority threads. On a multiprocessor system, both threads can run simultaneously, each on its own processor.

Applications should synchronize access to data structures to avoid race conditions. Code that assumes that higher priority threads run without interference from lower priority threads will fail on multiprocessor systems.

Memory Caching
When a processor writes to a memory location, the value is cached to improve performance. Similarly, the processor attempts to satisfy read requests from the cache to improve performance. Furthermore, processors begin to fetch values from memory before they are requested by the application. This can happen as part of speculative execution or due to cache line issues.

As a result, multiple processors can have different views of the system memory state because their caches are out of synch. For example, the following code is not safe on a multiprocessor system:

int iValue;
BOOL fValueHasBeenComputed = FALSE;
extern int ComputeValue();

void CacheComputedValue()
{
if (!fValueHasBeenComputed)
{
iValue = ComputeValue();
fValueHasBeenComputed = TRUE;
}
}

BOOL FetchComputedValue(int *piResult)
{
if (fValueHasBeenComputed)
{
*piResult = iValue;
return TRUE;
}
else
return FALSE;
}
There is a race condition in this code on multiprocessor systems because the processor that executes CacheComputedValue the first time may write fValueHasBeenComputed to main memory before writing iValue to main memory. Consequently, a second processor executing FetchComputedValue at the same time reads fValueHasBeenComputed as TRUE, because the new value of iValue is still in the first processor's cache.

Processors can be instructed to force their memory caches to agree with main memory with special instructions. Such instructions ensure that previous read and write requests have completed and are made visible to other processors, and to ensure that that no subsequent read or write requests have started. Examples are:

Functions which enter or leave critical sections.
Functions which signal synchronization objects.
Wait functions.
Interlocked functions
Consequently, the multiprocessor race condition above can be repaired as follows:

void CacheComputedValue()
{
if (!fValueHasBeenComputed) {
iValue = ComputeValue();
InterlockedExchange((LONG*)&fValueHasBeenComputed, TRUE);
}
}
The InterlockedExchange function ensures that the value of iValue is updated for all processors before the value of fValueHasBeenComputed is set to TRUE.

Alex
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.