2017-01-17 3 views
0

Я хочу, чтобы обсудить следующую структуру в golang от этого linkСтранный код для предотвращения непреднамеренного совместного использования

// Local per-P Pool appendix. 
    57 type poolLocal struct { 
    58  private interface{} // Can be used only by the respective P. 
    59  shared []interface{} // Can be used by any P. 
    60  Mutex     // Protects shared. 
    61  pad  [128]byte  // Prevents false sharing. 
    62 } 

выше структура может быть доступна только одна нить в то время, как используется мьютекс. Кодер заблокирует структуру в начале потока и разблокирует ее, когда поток завершится. Таким образом, память не разделяется между потоками. Таким образом, не более одного ядра будет иметь доступ к памяти. Итак, по моему мнению, ложного обмена не может быть здесь. Если ложного обмена не может произойти, почему кодер проложил структуру с дополнительными байтами (байт [128])? Я понимаю, что неправильно?

+5

Да, ваше понимание неверно: «Ложное разделение» не имеет ничего общего с несколькими потоками, обращающимися к одной и той же памяти (условие гонки, если вы пишете), но с строками кэша процессора: просто Google для «ложного обмена»: – Volker

+0

@ Volker Thabk you. Я понял. Позвольте мне пояснить. Пусть есть два потока t1 и t2, работающие на ядрах C1 и C2. Пусть t1 разрешено запускаться первым (теперь t2 ждет, когда есть заглушенный замок). Пусть t1 записывает данные в кеш l1 c1 (строка кэша, в которой хранится наша структура). Теперь t2 готов в C2. Но кэш L2 в C2 должен обновляться (по протоколу MESI) до новых значений. После этого t2 может продолжить работу. В этом случае происходит ложное совместное использование. Я прав? – user3219492

+0

Когда вы выполняете заполнение, каждому потоку будет выделена строка кэша в L1, которая будет указывать на разные ячейки памяти в L2 или более высокой памяти. Поскольку каждый поток работает с разными ячейками памяти, они не разделяются, поэтому MESI и обмен файлами не имеют никакого отношения. Я прав? – user3219492

ответ

2

Точки памяти в одной и той же строке кэша подлежат ложному обмену, что очень плохо для производительности. Размер строки кеша составляет от 32 до 128 байтов, в зависимости от модели процессора. 128 байт подушечка уменьшит шанс на одной строке кэша используется различными процессами и improvesthe Performace

, как я вижу, следующий будет лучше, так как это было бы более явным

type poolLocal struct { 
     _  [64]byte  // Prevents false sharing. 
     private interface{} // Can be used only by the respective P. 
     shared []interface{} // Can be used by any P. 
     Mutex     // Protects shared. 
     _  [64]byte  // Prevents false sharing. 
} 
+0

Ooops. Я не понимаю, как это ответ на мой вопрос. Мой вопрос: если только один поток имеет доступ к памяти, ложного обмена не может произойти, а затем почему программист добавил дополнительные биты. Теперь я его очистил (посмотрите на мои комментарии к вопросу). Цель состоит в том, чтобы размер структуры был кратным строке кеша. Почему это имеет значение, если оно заполнено в начале и/или в конце? – user3219492

+0

или в соответствии с этой ссылкой: http://www.geeksforgeeks.org/structure-member-alignment-padding-and-data-packing/ компилятор, похоже, изменяет порядок объявленных переменных. Таким образом, ваш стиль заполнения и тот, который размещен в вопросе, не имеет никакого значения. – user3219492

+0

@ user3219492 'false-sharing' не имеет ничего общего с потоками, обращающимися к той же memmory. Вы можете подумать об этом как о проблеме с производительностью из-за двух процессов, разделяющих одну и ту же строку кэша –

Смежные вопросы