При тестировании программы на масштабируемость я столкнулся с ситуацией, когда я должен сделать свою операцию memcpy как атомарную операцию. Я должен скопировать 64 байта данных из одного места в другое.
Я сталкивался с одним решением, которое использует вращение по переменной:
struct record{
volatile int startFlag;
char data[64];
volatile int doneFlag;
};
и псевдокод следует
struct record *node;
if ( node->startFlag ==0 ) { // testing the flag
if( CompareAndSwap(node->startFlag , 0 ,1 ) ) { // all thread tries to set, only one will get success and perform memcpy operation
memcpy(destination,source,NoOfBytes);
node->doneFlag = 1; // spinning variable for other thread, those failed in CompAndSwap
}
else {
while ( node->doneFlag==0 ) { // other thread spinning
; // spin around and/or use back-off policy
}
}}
Может ли это работать как атомарный memcpy? Хотя, если поток, выполняющий memcpy, прервется (до или после memcpy, но до установки doneFlag), другие будут продолжать вращаться. Или что можно сделать, чтобы сделать это атомным.
Ситуация похожа на то, что другой поток должен ждать, пока данные не будут скопированы, поскольку они должны сравнивать вставленные данные со своими собственными данными.
Я использую подход test-and-test-and-set в случае startFlag, чтобы уменьшить некоторые дорогостоящие атомарные операции.
Спин-блокировки также масштабируемы, но я измерил, что атомарные вызовы дают лучшую производительность, чем спин-блокировки, более того, я ищу проблемы, которые могут возникнуть в этом фрагменте.
И поскольку я использую свой собственный менеджер памяти, поэтому выделение памяти и бесплатные вызовы обходятся мне дорого, поэтому использование другого буфера и копирование в него содержимого делает установку указателя (так как размер указателя находится в атомарной операции) дорогостоящим, так как это требуется много вызовов mem-alloc и mem-free.
РЕДАКТИРОВАТЬ Я не использую мьютекс, потому что он не выглядит масштабируемым Более того, это всего лишь часть программы, поэтому критическая секция не такая уж мала что для большей критической секции трудно использовать атомарные операции).