2013-06-20 3 views
2

В настоящее время я пытаюсь реализовать общий стек в кластерной системе. Эта система имеет два адресных пространства, один закрытый и разделяемый между всеми процессорами.Изменение пространства стека

Как я могу изменить начало и конец стека в c-программировании?

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

+3

Что вам нужно это? Хотите, чтобы все темы использовали тот же стек? нет никакого способа, который когда-либо будет работать. Хотите передать указатели на вещи в один стек на другой поток? плохая идея, последствия синхронизации убьют вас. Хотите иметь общий стек, где любой поток может нажать/поп-вещи, теперь это совсем другая история. Поэтому, пожалуйста, уточните, чего вы на самом деле хотите достичь. – cmaster

+0

Моя идея с использованием общего стека для связи между потоками путем передачи указателей. Идея заключается в отправке указателя общей переменной на другой процессор по сообщению. Затем процессор мог получить доступ к этому общему адресу без необходимости копировать данные в свое пространство. – Hayder

+0

Кроме того, я не хочу использовать malloc или другую форму для распределения данных и передачи его указателя. Мне нужно выполнить процедуру, аналогичную модели OpenMP. – Hayder

ответ

1

Мой совет: избегайте прохода указателей на объекты на основе стека любой ценой. Если вы это сделаете, вам потребуется, чтобы поток отправки никогда не возвращался из функции, создавшей общий объект, до того, как он может proove, чтобы ни один другой поток не получал доступ к этому объекту. Это а) практически невозможно, и б) потребует блокировки блокировки производительности. Последствия неспособности сделать это правильно были бы полностью неопределенными ошибками! Не делай это!

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

+0

Благодарим вас за отзыв. Несколько версий OpenMP были перенесены в систему кластера или DSM. Моя платформа похожа на DSM. Я пытаюсь реализовать новую модель программирования, которая поддерживает приложение общей памяти в кластере. Поэтому мне нужно реализовать общий стек, как идея из раздела 4.6, из этой статьи: http://link.springer.com/chapter/10.1007%2F978-3-540-68555-5_7#page-1 – Hayder

-1

Позвольте мне изменить немного для ясности:

Вы просто пытаетесь изменить значение и определение STACK. STACK по сегодняшнему определению может использоваться только одним потоком для реальных операций STACK. STACK может совместно использоваться процессами или потоками для использования как обычная память. В этом случае вы действительно должны называть этот кусок памяти «общей памятью» не как «общий стек». Что вы действительно пытаетесь сделать или добиться в кластерной среде?

Вот пример, почему СТЕК не могут быть разделены ...

Thread-1 функция последовательности вызова:

main() 
    thr1_f1() 
     thr1_f2() 
      thr1_f3() 
    thr1_f4() 

Thread-2 функция последовательности вызова:

main() 
    thr2_f1() 
     thr2_f2() 
      thr2_f3() 
    thr2_f4() 

Предположим, что эти потоки разделяют STACK. Вот возможная последовательность вызовов функций ...

  1. Thread-1 находится в середине thr1_f1() и переходит в режим сна в процессорном ядре-1.
  2. Thread-2 начинается и находится в середине thr2_f2() и переходит в режим сна в процессорном ядре-2.
  3. Thread-1 появляется и вызывает thr1_f2(). Это перезапишет область STACK-2. Локальные переменные и параметры thr2_f2() теперь перепутаны.
  4. Thread-2 не сможет запустить и/или получить его обратный адрес в thr2_f1(). В зависимости от времени, он может получить некоторый адрес и сбросить ядро.
+0

любая ссылка для этого определение стека? – qdii

+0

Стек * может * делиться несколькими потоками. Понятие стека кактусов в одном, в котором родительский поток, имеющий существующий (кактус) стек, разделяет это со всеми своими параллельными дочерними элементами, каждый из которых получает собственное пространство стека, но может видеть/совместно использовать стек родителя. Наш параллельный язык программирования PARLANSE реализует эту концепцию напрямую, и мы используем ее прикладные программы, которые составляют порядка 2-4 миллионов строк кода. См. Http://www.semanticdesigns.com/Products/PARLANSE –

+0

@ Ира Бакстер: Не могли бы вы дать нам более подробную информацию о схеме стека кактусов? Кроме того, его можно реализовать в Linux? Заранее спасибо. – Hayder

1

Сомневаюсь, что вы можете добиться того, что вы хотите красиво на C (если вы не хотите изменить компилятор).

Вы говорите, что хотите использовать стиль программирования OpenMP. Это равносильно одному потоку верхнего уровня, который может развить детей для работы в общем пространстве, предоставляемом родителем. Необычный OpenMP делает это рекурсивно.

Для этого красиво, вы система/инструменты/компилятор должен быть в состоянии идентифицировать

* threads of computations 
* what variables are declared by each thread 
* what variables (or parts thereof) are offered by a thread to its thread children 

Если вы можете сделать эти вещи (и проще с поддержкой явного языка, OpenMP включена компиляторы помогают в этом процессе по прагмах OpenMP), то вы можете разделить данные на волоске в в 3-х частей:

1. storage accessed only by the thread, and not by its children 
2. storage declared by the thread, but accessed only by individual children (e.g., slices of arrays) 
3. storage read and written by the parent thread and its children 

на данный момент, вы можете рассмотреть макет из «локальные переменные» для потока, и, таким образом, чтобы стек пространство , Резервное хранилище нити распределено только в пространство стека родительского потока. Родительское, но обработанное дочерними элементами хранилище становится пространством, выделенным для локального пространства/стека. Хранение, прочитанное и написанное всеми, может быть размещено в любом месте, к которому он может быть доступен (в локальном пространстве родительского потока, в его стеке, в хранилище кучи), и для защиты данных требуется защита доступа. [Вы не можете принуждать традиционных компиляторов C сделать это для вас.]

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

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

[EDIT: После моего комментария о стеках кактусов, OP хотел узнать больше. Я буду включать здесь, а также некоторые указатели к ним]

Стек может использоваться несколькими потоками. Понятие стека кактусов - это тот, в котором родительский поток, имеющий существующий (кактус) стек, делится со всеми своими параллельными дочерними элементами, каждый из которых получает собственное пространство стека, но может видеть/совместно использовать стек родителя.

Наш параллельный язык программирования PARLANSE реализует эту концепцию напрямую, и мы используем ее в прикладных программах, которые составляют порядка 2-4 миллионов строк кода. Каждая функция вызывает кучу - выделяет свои записи активации (используя локальный распределитель потока для скорости) и имеет доступ ко всем сегментам родительского стека с помощью лексического уровня до адресации, реализуемой как поле указателей, переданных родителем его дочернему элементу на вызов функции. В блоге Intel ниже описаны именно те причины, по которым мы это сделали.

Ссылки:

+0

В оригинальной модели OpenMP стек основного потока разделяется между всеми потоками. Таким образом, gcc-компилятор собирает все указатели на эту локальную/глобальную переменную и помещает их в метаданные (структуру) и передает другим потокам в качестве аргумента. Затем компилятор обменивает все ссылки переменной на указатель (например, int a ---> int * a). В конце концов, все потоки могут получить к ним доступ с помощью указателя. – Hayder

+0

В моей реализации мне нужно сделать стек главного процессора видимым для всего другого процессора, выделив его в известном адресном пространстве, а затем переназначив адресное пространство каждого подчиненного процессора на тот же виртуальный адрес основного ядра. В конце концов, каждый процессор мог получить доступ к этой переменной, используя оригинальный механизм gcc-компилятора. Таким образом, изменить первоначальную реализацию OpenMP-подхода не потребуется. – Hayder

+0

Что касается схемы OpenMP GCC: фраза «стек основного потока является общим» легко неверно истолкована. То, что вы описываете, имеет смысл, но стек основного потока не используется в том смысле, что все потоки * устанавливают указатель стека * в местоположение или событие главного стека в любом месте внутри него; скорее, каждый поток, как вы описали, имеет свой собственный стек, а ящик указателей на интересные места в главном стеке передается детям. Итак, 1) это не похоже на то, что ваш вопрос должен просить, и 2) для этого требуется помощь компилятора GCC. Можете ли вы изменить свой компилятор? –