Безопасность memcpy() в соседних областях памяти

Недавно я задал вопрос об использовании volatile и ему было предложено прочитать несколько очень информативных статей от Intel и других, в которых обсуждаются барьеры памяти и их использование. Однако после прочтения этих статей я стал довольно параноиком.

У меня 64-битная машина. Безопасно ли memcpy в смежные, непересекающиеся области памяти из нескольких потоков? Например, скажем, у меня есть буфер:

char buff[10];

Безопасно ли всегда, чтобы один поток копировал memcpy в первые 5 байтов, а второй поток копировал в последние 5 байтов?

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


person JaredC    schedule 14.01.2011    source источник


Ответы (4)


Безопасно, да. Производительность, нет, по крайней мере, в этом ограниченном примере. Помните, что одна строка кэша не может находиться сразу в двух ядрах. Вы заставите ядро ​​A ждать, пока ядро ​​B будет писать в буфер, а затем ждать, пока память будет передана, а затем писать в нее. Копии многоядерной памяти должны быть очень большими, чтобы избежать этого эффекта.

person Puppy    schedule 14.01.2011
comment
Это зависит от процессора, если память была объявлена ​​энергозависимой, и от уровня оптимизации компилятора. Как правило, каждое ядро ​​записывает в свою собственную копию кеша, которую процессор разрешает позже во время последующей очистки. Это говорит о том, что фактический барьер синхронизации памяти совершенно необходим, чтобы получить детерминированное поведение от фактических попыток чтения памяти, которая была записана. - person Adam Norberg; 15.01.2011
comment
x86/x64 и многие другие процессоры когерентны с кэшем (en.wikipedia.org/wiki/Cache_coherency ). Два ядра могут содержать одну и ту же строку кэша, и обе копии всегда будут обновляться, чтобы они содержали одно и то же значение. Конечно, как уже говорилось, доступ к одной и той же строке кэша с двух ядер оказывает огромное влияние на производительность. - person Timo; 15.01.2011
comment
@Adam: К счастью, меня беспокоит только запись - любое чтение произойдет в далеком будущем. В противном случае я, вероятно, стал бы еще более параноиком. - person JaredC; 15.01.2011
comment
Я смотрел видео о последней библиотеке параллелизма Microsoft, и они сказали, что совместное использование строк кэша было самой большой проблемой, с которой они столкнулись, чтобы заставить их, казалось бы, хороший код действительно работать. Это изменит масштабирование кода с 40% на 100% масштабирование на 24 ядрах, когда оно будет исправлено. Ложное совместное использование — это не мелкая проблема с производительностью, а серьезная проблема. - person Puppy; 15.01.2011
comment
Однако Адам по-прежнему прав в том, что это зависит от процессора. Спрашивающий только говорит, что у меня 64-битная машина. Я на 99,9% уверен, что это означает x64, но не все 64-битные процессоры являются x64/IA64. Ходят разговоры о 64-битной ARM, а архитектуры ARM не всегда имеют когерентные кэши, и в этом случае эти соседние записи, возможно, могут быть не потокобезопасными. Тогда ложное совместное использование становится проблемой корректности, а не только производительности. - person Steve Jessop; 15.01.2011

Да, это совершенно безопасно, сериализация доступа к шине памяти осуществляется аппаратно.

person Gene Bushuyev    schedule 14.01.2011

Пока каждый экземпляр memcpy считает, что записывает только свою часть буфера, он полностью безопасен. Выделение массива в любой форме в C++ очень низкоуровневое; это непрерывный блок памяти, выделенный для программы соответствующего размера, а массив как объект, который существует как что-то кроме указателя, является просто иллюзией. Дайте memcpy непересекающиеся диапазоны массива, и у него не будет возможности узнать, что это не просто два совершенно отдельных массива, которые случайно оказались рядом друг с другом. Записи не будут мешать.

person Adam Norberg    schedule 14.01.2011
comment
MemCpy? Больше похоже на memcpy. Более того, ОП обеспокоен проблемами одновременного доступа к памяти из разных потоков. - person David Heffernan; 14.01.2011
comment
Ваше тактичное и вежливое редактирование копий приветствуется в духе сотрудничества, в котором оно было предложено. В любом случае, ОП обеспокоен проблемами одновременного доступа к непересекающимся соседним областям памяти в разных потоках, на что я и ответил. - person Adam Norberg; 15.01.2011

Да, это совершенно не связано с какими-либо событиями перед заказом. это просто копирование байтов.

person time4tea    schedule 14.01.2011