2009-10-03 1 views
0

В настоящее время я работаю над критичным для производительности приложением, которое содержит устаревший код c (вариант SPICE).Включение Legacy-C C++

Проблема заключается в следующем:

Создатели унаследованного кода С, по-видимому считал, что использование передачи аргументов является одним из самых больших зол современной эпохи. Таким образом, около 90% всех переменных были объявлены глобально.

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

Моя идея состояла в том, чтобы инкапсулировать устаревший код c (который я уже немного изменил для компиляции g ++), чтобы можно было создать несколько объектов для устаревшего кода, избавляя от необходимости многих блокировок мьютексов. Очевидно, что глобальные переменные будут, таким образом, инкапсулированы как переменные-члены.

Это принесло еще одну проблему к столу. Унаследованные кодеры также не верят в инициализацию глобальных переменных; вероятно, так как C имеет тенденцию инициализировать глобальные переменные до 0. Элементы-члены C++ не являются швами, чтобы получить одинаковое обращение. Несколько переменных должны быть инициализированы до 0 для правильной работы устаревшего кода c. Но найти эти переменные оказалось довольно сложным из-за огромного количества используемых глобальных переменных.

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

Мои вопросы заключаются в следующем:

  1. Я правильно в предположении, что инкапсуляция кода C будет быстрее , чем использование около 90 мьютекса замков?

  2. Есть ли простой способ поиска неинициализированной переменной-члена? (Насколько я понимаю, gcc может делать это только для автоматических переменных). Чтобы я мог инициализировать только критические переменные?

  3. Если не вопрос 2 ... есть ли быстрый и чистый способ инициализировать все переменные-члены без использования обычного метода инициализации конструктора?

  4. Или (длинный снимок) есть быстрый способ следования программному потоку, чтобы я мог включить аргумент, проходящий сам?

Любая помощь будет очень оценена. N.B.

+0

Какой SPICE вариант и какие функции? Я быстро взглянул на источник SPICE3, похоже, не соответствует вашему описанию. –

ответ

3
  1. Да. Если вы можете поместить состояние в объекты, к которым вы передаете указатели, это будет быстрее, чем блокировка, если вы действительно используете потоки.
  2. Нет, нелегко найти унифицированные переменные-члены. По сути, это потребует выполнения анализа всего кода, который он обычно не может выполнять (из-за существования библиотек)
  3. Если вы поместили все данные в структуру старого стиля (то есть без методов, без доступа) , вам разрешено memset() вся структура до нуля. Это приведет к инициализации так же, как инициализируются глобальные переменные (что C гарантирует инициализацию - до нуля).
  4. Если вы, быстро, имеете в виду «автоматический», тогда ответ, вероятно, «нет».
+0

WRT memset, вы можете избежать этого, пока у вас нет виртуальной таблицы. То есть вы можете иметь функции-члены, если они не являются виртуальными, и вы можете иметь наследование, пока оно тоже не является виртуальным. Мой совет - обернуть старые переменные C в структуру POD и поместить их внутри класса. memset struct в конструкторе класса, но добавьте любые новые переменные-члены в класс непосредственно (а не в структуру). – Steve314

+0

Стив: WRT memset, самый простой способ - поместить их в свою собственную структуру и использовать ее в качестве базового класса. – peterchen

+0

@Steve: это не совсем правильно. Если у вас есть члены в структуре, которые имеют нетривиальный конструктор, вы также не должны инициализировать структуру с memset. –

0

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

+0

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

+0

В UNIX и Linux создание нового процесса с помощью 'fork' довольно дешево. Весь код уже находится в памяти, а память может быть помечена как «копировать при записи». – MSalters

1

Это вы собираетесь использовать несколько потоков, вам нужно либо устранить, либо заблокировать данные, разделяемые между потоками. Создание старого, не потокового безопасного повторного ввода кода будет означать много работы и много отладки. Если у вас не так много времени, чтобы вникать в устаревший код, я бы не попробовал. Вы открываете огромную банку червей.

  • Вы можете обеспечить начальные 0 значений для ваших глобальных переменных в g ++ с -fno-common. См. Руководство gcc.

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

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

С уважением, Matt

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

  • Нет связанных вопросов^_^