Что такое модель памяти C ++ 03 для параллелизма? - PullRequest
34 голосов
/ 21 октября 2008

Какая модель памяти для параллелизма в C ++ 03?

(А C ++ 11 меняет модель памяти для лучшей поддержки параллелизма?)

Ответы [ 7 ]

34 голосов
/ 21 октября 2008

Модель памяти C ++ - это спецификация того, когда и почему физическая память считывается / записывается относительно кода C ++.

До следующего стандарта C ++ модель памяти C ++ такая же, как и в C. В стандарте C ++ 0x ожидается включение подходящей модели памяти для многопоточности (см. здесь ), и возможно, он станет частью следующего пересмотра стандарта C, C1X. Текущий элементарен:

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

Итак, текущее состояние: Операции с памятью C ++ указываются только тогда, когда у вас есть 1 процесс с его основным потоком и не пишущий код, который зависит от определенного порядка чтения / записи переменных, и все. По сути, это означает, что помимо традиционной программы hello world вы облажались.

Конечно, вам будет предложено добавить, что "это работает сегодня на моей машине, вы не можете быть правы" . Правильное предложение было бы "сегодня оно работает на моей машине с этой конкретной комбинацией аппаратного обеспечения, операционной системы (библиотеки потоков) и компилятора, которые достаточно хорошо знают друг друга, чтобы реализовать что-то, что несколько работает, но, вероятно, в какой-то момент сломается «.

Хорошо, хорошо, это немного грубо, но, черт возьми, даже Херб Саттер признает, что (только что прочитал вступление), и он говорит обо всех версиях одного из самых распространенных наборов инструментов C / C ++ до 2007 года ...

Стандартный комитет C ++ пытается придумать что-то, что решит все эти проблемы, но при этом будет менее ограниченным (и, следовательно, более эффективным), чем модель памяти Java.

Ханс Бём собрал здесь некоторые ссылки на статьи по этому вопросу, как академические, так и из комитета C ++.

23 голосов
/ 21 октября 2008

Видя некоторые другие ответы, кажется, что многие программисты на C ++ даже не знают, что означает «модель памяти», о которой вы спрашиваете.

Вопрос касается модели памяти в том смысле: какие гарантии (если таковые имеются) существуют в отношении переупорядочения записи / чтения (что может произойти на стороне компилятора или на этапе выполнения)? Этот вопрос очень важен для многопоточного программирования, так как без таких правил написание правильных многопоточных программ невозможно, и несколько удивительная истина в том, что в настоящее время не хватает модели явной памяти, многие многопоточные программы работают более или менее «по счастливой случайности» - чаще всего благодаря компиляторы, предполагающие наложение указателей на вызовы функций. - см. Потоки не могут быть реализованы в виде библиотеки

В текущем C ++ нет стандартной модели памяти. Некоторые компиляторы определяют модель памяти для изменчивых переменных, но это нестандартно. C ++ 0x определяет новые «атомарные» примитивы для этой цели. Исчерпывающая отправная точка для проверки того, что является недавним состоянием, находится в Потоки и модель памяти для C ++

Важными ссылками также являются Модель памяти параллелизма , Атомарные типы и C ++ Упорядочение зависимостей данных: модель атомов и памяти стандартные предложения.

2 голосов
/ 21 октября 2008

Как насчет проверки документов на веб-сайте комитета по стандартизации C ++:

2 голосов
/ 21 октября 2008

К сожалению, в C ++ нет «Стандартной модели памяти», как в Java. Фактическая реализация оставлена ​​на усмотрение компилятора, библиотек времени выполнения и процессоров.

Таким образом, модель памяти C ++ == хаотическая смесь моделей, что означает, что вам всегда нужно пытаться писать безопасный код, который не зависит от конкретной модели памяти, и это также относится к многопоточному программированию, потому что Компилятор может выполнить любую оптимизацию за пределами критической секции, даже вне обработки заказа!

1 голос
/ 04 мая 2010

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

http://rsim.cs.uiuc.edu/~sadve/Publications/computer96.pdf

0 голосов
/ 21 октября 2008

В двух словах, модель памяти C ++ состоит из ...

  • Стек, растущий вниз - то есть, когда вы перемещаете кадр стека, указатель стека имеет значение меньше, чем было

  • Куча, которая растет вверх, то есть конечный адрес вновь выделенной памяти, больше, чем она была до памяти. Вы выделяете память в куче, используя malloc () или new. Если в куче недостаточно памяти, то malloc (или новая) вызывает системную функцию brk () sbrk (), чтобы увеличить размер кучи. Если вызов brk () или sbrk () завершится неудачно, то malloc или new завершатся неудачно с исключением нехватки памяти.

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

  • Распределитель памяти, malloc, который выделяет память в виде 8-битных байтов. Новый также выделяет память, но объем памяти, который он выделяет, зависит от размера обновляемого объекта.

  • Текстовое пространство, которое содержит исполняемый код. Текст находится под кучей. Вы не можете изменить текстовое пространство во время выполнения

Программа может иметь другие специальные разделы ниже текста.

Вы можете увидеть, как программа организована статически (до загрузки), используя objdump в системах Linux.

Я заметил, что, хотя вы не упомянули об этом в своем вопросе, "параллелизм" - это одно из ключевых слов, которые вы присвоили этому вопросу. Системы потоков выделяют дополнительное пространство потоков в куче для каждого потока, а затем управляют указателем стека для переключения между потоками.

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

0 голосов
/ 21 октября 2008

Краткий ответ: нет

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

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

Архитектура x86 также позволяет адресовать память с использованием дескрипторов сегментов. Это целый набор «червей», который на самом деле не использовался со времен Win16, и если вам повезет, вам никогда не придется иметь с этим дело.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...