Я написал следующую короткую программу C ++, чтобы воспроизвести эффект ложного обмена, как описано Herb Sutter: < /p>
, скажем, мы хотим выполнить общее количество целостных операций рабочей нагрузки, и мы хотим, чтобы они были одинаково распространены по числу (параллельно) потоков. Для целей этого теста каждый поток будет увеличивать свою собственную выделенную переменную из массива целых чисел, поэтому процесс может быть идеально параллелизируемым. < /P>
void thread_func(int* ptr)
{
for (unsigned i = 0; i < WORKLOAD / PARALLEL; ++i)
{
(*ptr)++;
}
}
int main()
{
int arr[PARALLEL * PADDING];
thread threads[PARALLEL];
for (unsigned i = 0; i < PARALLEL; ++i)
{
threads = thread(thread_func, &(arr[i * PADDING]));
}
for (auto& th : threads)
{
th.join();
}
return 0;
}
< /code>
Я думаю, что идея легко понять. Если вы установили < /p>
#define PADDING 16
< /code>
Каждый поток будет работать на отдельной линии кэша (при условии, что длина линии кэша составляет 64 байта). Таким образом, результатом будет линейное увеличение ускорения до параллелей> # ядра. Если, с другой стороны, накладка установлена на любое значение ниже 16, нужно столкнуться с серьезным конфликтом, поскольку, по крайней мере, два потока в настоящее время могут работать на одной и той же линии кэша, которая, однако, защищена встроенным аппаратным мутекс. Мы ожидаем, что наше ускорение не только будет сублинейным в этом случае, но даже будет всегда
Теперь мои первые попытки почти удовлетворили эти ожидания, однако минимальное значение прокладки, необходимое для того, чтобы избежать ложного обмена, составляли около 8, а не 16. Я был довольно озадачен в течение около полчаса, пока я не пришел к очевидному выводу, что нет гарантии, что моя массива будет точно выровнен в начале линии Cache. Фактическое выравнивание может варьироваться в зависимости от многих условий, включая размер массива. < /p>
В этом примере, конечно, нам нет необходимости, чтобы массив выровнен особым образом, потому что мы можем просто оставить набивку в 16 лет, и все работает нормально. Но можно представить случаи, когда это имеет значение, независимо от того, выровнена ли определенная структура с линией кеша или нет. Следовательно, я добавил несколько строк кода, чтобы получить некоторую информацию о фактическом выравнивании моего массива. < /P>
int main()
{
int arr[PARALLEL * 16];
thread threads[PARALLEL];
int offset = 0;
while (reinterpret_cast(&arr[offset]) % 64) ++offset;
for (unsigned i = 0; i < PARALLEL; ++i)
{
threads = thread(thread_func, &(arr[i * 16 + offset]));
}
for (auto& th : threads)
{
th.join();
}
return 0;
}
< /code>
Несмотря на то, что это решение получило хорошо для меня в этом случае, я не уверен, что это будет хорошим подходом в целом. Итак, вот мой вопрос: < /p>
Есть ли какой -либо общий способ, чтобы объекты в памяти выровнены по линиям кэша, отличных от того, что я сделал в приведенном выше примере?>
Подробнее здесь: https://stackoverflow.com/questions/182 ... -alignment
Кэш -линии, ложное обмен и выравнивание ⇐ C++
Программы на C++. Форум разработчиков
1751641282
Anonymous
Я написал следующую короткую программу C ++, чтобы воспроизвести эффект ложного обмена, как описано Herb Sutter: < /p>
, скажем, мы хотим выполнить общее количество целостных операций рабочей нагрузки, и мы хотим, чтобы они были одинаково распространены по числу (параллельно) потоков. Для целей этого теста каждый поток будет увеличивать свою собственную выделенную переменную из массива целых чисел, поэтому процесс может быть идеально параллелизируемым. < /P>
void thread_func(int* ptr)
{
for (unsigned i = 0; i < WORKLOAD / PARALLEL; ++i)
{
(*ptr)++;
}
}
int main()
{
int arr[PARALLEL * PADDING];
thread threads[PARALLEL];
for (unsigned i = 0; i < PARALLEL; ++i)
{
threads[i] = thread(thread_func, &(arr[i * PADDING]));
}
for (auto& th : threads)
{
th.join();
}
return 0;
}
< /code>
Я думаю, что идея легко понять. Если вы установили < /p>
#define PADDING 16
< /code>
Каждый поток будет работать на отдельной линии кэша (при условии, что длина линии кэша составляет 64 байта). Таким образом, результатом будет линейное увеличение ускорения до параллелей> # ядра. Если, с другой стороны, накладка установлена на любое значение ниже 16, нужно столкнуться с серьезным конфликтом, поскольку, по крайней мере, два потока в настоящее время могут работать на одной и той же линии кэша, которая, однако, защищена встроенным аппаратным мутекс. Мы ожидаем, что наше ускорение не только будет сублинейным в этом случае, но даже будет всегда
Теперь мои первые попытки почти удовлетворили эти ожидания, однако минимальное значение прокладки, необходимое для того, чтобы избежать ложного обмена, составляли около 8, а не 16. Я был довольно озадачен в течение около полчаса, пока я не пришел к очевидному выводу, что нет гарантии, что моя массива будет точно выровнен в начале линии Cache. Фактическое выравнивание может варьироваться в зависимости от многих условий, включая размер массива. < /p>
В этом примере, конечно, нам нет необходимости, чтобы массив выровнен особым образом, потому что мы можем просто оставить набивку в 16 лет, и все работает нормально. Но можно представить случаи, когда это имеет значение, независимо от того, выровнена ли определенная структура с линией кеша или нет. Следовательно, я добавил несколько строк кода, чтобы получить некоторую информацию о фактическом выравнивании моего массива. < /P>
int main()
{
int arr[PARALLEL * 16];
thread threads[PARALLEL];
int offset = 0;
while (reinterpret_cast(&arr[offset]) % 64) ++offset;
for (unsigned i = 0; i < PARALLEL; ++i)
{
threads[i] = thread(thread_func, &(arr[i * 16 + offset]));
}
for (auto& th : threads)
{
th.join();
}
return 0;
}
< /code>
Несмотря на то, что это решение получило хорошо для меня в этом случае, я не уверен, что это будет хорошим подходом в целом. Итак, вот мой вопрос: < /p>
Есть ли какой -либо общий способ, чтобы объекты в памяти выровнены по линиям кэша, отличных от того, что я сделал в приведенном выше примере?>
Подробнее здесь: [url]https://stackoverflow.com/questions/18236603/cache-lines-false-sharing-and-alignment[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия