Re[6]: Lock-free array-based stack
От: remark Россия http://www.1024cores.net/
Дата: 01.03.10 16:41
Оценка: 36 (5)
Здравствуйте, Jolly Roger, Вы писали:

JR>Набравшись наглости, рискну обратиться с просьбой — Вы не могли бы раскритиковать ещё один пример


Вроде выглядит нормально. Это классический стек, про который известно, что он работает... если тут, конечно, нет никаких глупых опечаток, но вроде я не вижу.

Единственное, вызовы Thread.MemoryBarrier() излишни, но очень дороги. Их надо убрать.

Плюс, я бы убрал переменную count, т.к. пользы от неё обычно мало, а стоимость Push/Pop она удваивает. Кстати, она тут может возвращать -1, что может быть весьма удивительно для вызывающего кода. Если она *действительно* нужна, то я бы перенёс Interlocked.Increment(ref count) в начало метода — обычно лучше вернуть на 1 больше, чем на 1 меньше.

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

Но это всё исключительно по производительности, а не по корректности.
В итоге получается что-то типа такого, я думаю это должно работать видимо пошустрее на синтетическом тесте:


        public T Pop()
        {
            StackItem<T> tmpHead = Head;
            StackItem<T> tmpHead2;
            for (;;)
            {
                if (tmpHead == null)
                    return null;
                tmpHead2 = Interlocked.CompareExchange<StackItem<T>>(ref Head, tmpHead.Next, tmpHead);
                if (tmpHead2 == tmpHead)
                    return tmpHead.Value;
                tmpHead = tmpHead2;
            } 
        }

        public void Push(T data)
        {
            StackItem<T> item = new StackItem<T>(data);
            StackItem<T> tmpHead = Head;
            StackItem<T> tmpHead2;
            for (;;)
            {
                item.Next = tmpHead;
                tmpHead2 = Interlocked.CompareExchange<StackItem<T>>(ref Head, item, tmpHead);
                if (tmpHead2 == tmpHead)
                    return;
                tmpHead = tmpHead2;
            }
        }
    }



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.