LINUX.ORG.RU

SMP и перации с памятью


0

0

Возможна-ли такая ситуация когда один поток пишет в область памяти (размером 64бита на 64-й платформе либо 32бита на 32-тной), а второй без всякой синхронизации читает эту память и при вычитке он получает не доконца записанную память. Например старое значение 0xffffffff, писатель туда пишет 0xaaaaaaaa, а читатель вычитывает 0xaaaaffff. Как я полагаю, то наверное всё зависит от архитектуры..

> Возможна-ли такая ситуация когда один поток пишет в область памяти (размером 64бита на 64-й платформе либо 32бита на 32-тной), а второй без всякой синхронизации читает эту память и при вычитке он получает не доконца записанную память. Например старое значение 0xffffffff, писатель туда пишет 0xaaaaaaaa, а читатель вычитывает 0xaaaaffff. Как я полагаю, то наверное всё зависит от архитектуры..

ну "грязного" значения он получить не может, а вот рейсы могут и возникнуть. aka после того, как поток A на CPU0 уже записал новое значение X, поток B на CPU1 при последующем чтении все еще считывает старое значение Y. кеш - штука тонкая..

// wbr

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


ну если про Intel то:

253668 - Intel 64 and IA-32 Architectures - Software Developer Manual - System Programming Guide Part1.pdf

--- cut ---
7.1.1 Guaranteed Atomic Operations
The Intel486 processor (and newer processors since) guarantees that the following
basic memory operations will always be carried out atomically:
• Reading or writing a byte
• Reading or writing a word aligned on a 16-bit boundary
• Reading or writing a doubleword aligned on a 32-bit boundary
The Pentium processor (and newer processors since) guarantees that the following
additional memory operations will always be carried out atomically:
• Reading or writing a quadword aligned on a 64-bit boundary
• 16-bit accesses to uncached memory locations that fit within a 32-bit data bus
The P6 family processors (and newer processors since) guarantee that the following
additional memory operation will always be carried out atomically:
• Unaligned 16-, 32-, and 64-bit accesses to cached memory that fit within a cache
line
Accesses to cacheable memory that are split across bus widths, cache lines, and
page boundaries are not guaranteed to be atomic by the Intel Core 2 Duo, Intel Core
Duo, Pentium M, Pentium 4, Intel Xeon, P6 family, Pentium, and Intel486 processors.
The Intel Core 2 Duo, Intel Core Duo, Pentium M, Pentium 4, Intel Xeon, and P6
family processors provide bus control signals that permit external memory
subsystems to make split accesses atomic; however, nonaligned data accesses will
seriously impact the performance of the processor and should be avoided.
--- cut ---

// wbr

klalafuda ★☆☆
()

> Как я полагаю, то наверное всё зависит от архитектуры..

Все верно.

Обычно этот вопрос рассматривается в другом (более общем) контексте: http://www.linuxjournal.com/article/8211

anonymous
()

2TaranSergey:

> Возможна-ли такая ситуация когда один поток пишет в область памяти (размером 64бита на 64-й платформе либо 32бита на 32-тной), а второй без всякой синхронизации читает эту память и при вычитке он получает не доконца записанную память. Например старое значение 0xffffffff, писатель туда пишет 0xaaaaaaaa, а читатель вычитывает 0xaaaaffff. Как я полагаю, то наверное всё зависит от архитектуры..

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

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

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

> Если область памяти выровнена по границе слова

А можно пояснить по подробней, что это значит ?
И как это сделать ? Например,
int mass[100]; как выравнять ?

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

Если не задавать специально опции компилятору, не указывать аттрибуты у объектов, и не приводить указатели от одного типа к другому, то память выравнивается правильно на всех архитектурах.

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

А если все же надо выравнивать произвольный буфер на определенную границу то можно поступить так:

#define ALIGN_UP(addr,size) (((void *)(addr)+((size)-1))&(~((size)-1)))
int *p=(int *)ALIGN_UP(buf, sizeof(int))

следует помнить, что возможно p>buf и размер buf должен быть достаточен

Лично я бы забил на производительность и использовал атомарные операции доступа к данным, например из кросплатформенной glib

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