глобальные переменные
От: ra88  
Дата: 20.01.09 17:28
Оценка:
Здравствуйте!

У меня вопрос больше академического характера Просьба отнестись к этому вопросу адекватно.


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

у меня два варианта возможного дизайна. В первом я объявляю статическую перемнную типа структуры и при где-нибудь её инициализирую, а потом где-нибудь удаляю. При этом все функции пользуются только этой переменной.
Первый:
....
typedef struct {
  ...
  ...
} my_type_t;

static my_type_t my_var;

int create_my_var();
int release_my_var();

int do_something1();
int do_something2();
....


Во втором варианте я предоставляю пользователю завести переменную типа структуры и потом каждая функция получает её как параметер.
Второй:
....
typedef struct {
  ...
  ...
} my_type_t;

int create_my_var(my_type_t*);
int release_my_var(my_type_t*);

int do_something1(const my_type_t*);
int do_something2(const my_type_t*);
....


Вопрос: Есть ли какое-то преимущество одного из методов с точки зрения быстродействия?

Во втором варианте вроде бы более или менее понятно. При вызове функции адрес структуры помещается в регистер, вызывается цалл и функция берёт адрес из регистра.
Что происходит в первом варианте?
while true;
Re: Какой язык имеется в виду? Видимо С++?
От: Erop Россия  
Дата: 20.01.09 18:35
Оценка:
Здравствуйте, ra88, Вы писали:

R>Что происходит в первом варианте?

Адреса полей являются литералами в коде.

В общем случае подход со статической переменной быстрее. Особенно если ты будешь свою структуру инициализировать агрегатом, так как тогда у компилятора будут шансы догадаться до значений и по адресам вообще не лазить...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Какой язык имеется в виду? Видимо С++?
От: ra88  
Дата: 20.01.09 18:57
Оценка:
извиняюсь. как всегда забыл указать важное. Использую gcc 4.3.2 (без плюсов).

R>>Что происходит в первом варианте?

E>Адреса полей являются литералами в коде.

Я могу путаться в терминологии, немного не понятно, что ты имеешь ввиду? Под полями в данном случае ты понимаешь поля структуры? Или что-то иное? Вопрос был, куда и с какой скоростью функции обращаются за глобальной статической переменоой? Есть что-нибудь вроде таблицы глобальных переменных? Если есть, то где она и как быстро до неё добраться?

E>В общем случае подход со статической переменной быстрее. Особенно если ты будешь свою структуру инициализировать агрегатом, так как тогда у компилятора будут шансы догадаться до значений и по адресам вообще не лазить...
while true;
Re: глобальные переменные
От: Mr.Cat  
Дата: 20.01.09 19:07
Оценка: 1 (1)
Здравствуйте, ra88, Вы писали:
R>Вопрос: Есть ли какое-то преимущество одного из методов с точки зрения быстродействия?

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

Хотя первый метод и кажется навскидку быстрее, я бы
1)Предположил, что оверхед от второго варианта будет весьма невелик.
2)Прогнал бы какие-нибудь синтетические тесты, если производительность реально настолько важна.
Re[2]: глобальные переменные
От: Mr.Cat  
Дата: 20.01.09 19:10
Оценка: :))
Здравствуйте, Mr.Cat, Вы писали:
MC>при уровне, стремящемся к O3.

кстати, задумался тут. Почему уровни оптимизации у того же GCC маркируются натуральными числами? Почему между -O2 и -O3 нет, например, -Oe, а до -O2 нет -Osqrt2?
Re[3]: Какой язык имеется в виду? Видимо С++?
От: Erop Россия  
Дата: 20.01.09 19:23
Оценка: 1 (1)
Здравствуйте, ra88, Вы писали:

Для начала не кисло бы описать
1) Язык (С или С++)
2) Компилятор
3) Платформу

Я отвечаю в предположении: С++, MSVC, OS Windows XP

R>Я могу путаться в терминологии, немного не понятно, что ты имеешь ввиду? Под полями в данном случае ты понимаешь поля структуры? Или что-то иное? Вопрос был, куда и с какой скоростью функции обращаются за глобальной статической переменоой? Есть что-нибудь вроде таблицы глобальных переменных? Если есть, то где она и как быстро до неё добраться?


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

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


Что такое агрегат -- знаешь? Это конструкция типа
const static struct MyData {
    int Field1;
    int Field2;
    int Field3;
} = { 
   1, 2, 4 // это вот и есть агрегат
};
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: глобальные переменные
От: alexeiz  
Дата: 20.01.09 19:53
Оценка: 1 (1)
Здравствуйте, ra88, Вы писали:

R>Вопрос: Есть ли какое-то преимущество одного из методов с точки зрения быстродействия?


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

Я бы предложил тебе сделать my_type классом, а do_something1/do_something2 — методами класса. Тогда тебе, во-первых, не прийдется оперировать глобальными объектами, и, во-вторых, твой код будет чище и понятнее, чем, когда ты просто структуру пихаешь в параметры функций.
Re[2]: глобальные переменные
От: Erop Россия  
Дата: 20.01.09 20:06
Оценка:
Здравствуйте, alexeiz, Вы писали:

A>Я бы предложил тебе сделать my_type классом, а do_something1/do_something2 — методами класса. Тогда тебе, во-первых, не прийдется оперировать глобальными объектами, и, во-вторых, твой код будет чище и понятнее, чем, когда ты просто структуру пихаешь в параметры функций.


А ты уверен, что это плюсы?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: глобальные переменные
От: rg45 СССР  
Дата: 20.01.09 20:18
Оценка:
Здравствуйте, ra88, Вы писали:

R>...

R>Вопрос: Есть ли какое-то преимущество одного из методов с точки зрения быстродействия?
R>Во втором варианте вроде бы более или менее понятно. При вызове функции адрес структуры помещается в регистер, вызывается цалл и функция берёт адрес из регистра.
R>Что происходит в первом варианте?

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

--
Справедливость выше закона. А человечность выше справедливости.
Re[4]: Какой язык имеется в виду? Видимо С++?
От: ra88  
Дата: 20.01.09 22:34
Оценка: +1
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, ra88, Вы писали:


E>Для начала не кисло бы описать

E>1) Язык (С или С++)
E>2) Компилятор
E>3) Платформу

извиняюсь ещё раз. первое и второе указал вроде бы в ответе, третье думал следует из контекста, но на всякий случай ещё раз:
1) С
2) gcc-4.3.2
3) linux

E>Да, поля структуры. Эта структура будет расположена в памяти по фиксированному адресу. При этом, она может даже не инициализироваться, а просто грузиться из экзешника.

E>Соответсвенно код, обращающийся кданным в такой структуре будет знать адреса данных непосредственно, и сможет обращаться непосредственно по ним. То есть инструкции будут содержать адреса данных непосредственно в себе
E>Что такое агрегат -- знаешь? Это конструкция типа
const static struct MyData {
E>    int Field1;
E>    int Field2;
E>    int Field3;
E>} = { 
E>   1, 2, 4 // это вот и есть агрегат
E>};

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

Тем не менее многое прояснилось. Думаю, что справедливо полагать, что первый вариант должен быть быстрее. GCC переводит статическую структуру в данном случае в заклинание типа
 98     .local  my_var
 99     .comm   my_var,16,16

что на сколько я понимаю означает, что резервируется память в (в данном случае) в 16 байт с соответствующиим выравниванием и закрепляется за my_var, который потом и используется в коде.
while true;
Re[2]: глобальные переменные
От: ra88  
Дата: 20.01.09 22:38
Оценка:
Здравствуйте, Mr.Cat, Вы писали:

MC>Здравствуйте, ra88, Вы писали:

R>>Вопрос: Есть ли какое-то преимущество одного из методов с точки зрения быстродействия?

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


MC>Хотя первый метод и кажется навскидку быстрее, я бы

MC>1)Предположил, что оверхед от второго варианта будет весьма невелик.
MC>2)Прогнал бы какие-нибудь синтетические тесты, если производительность реально настолько важна.

согласен про оптимизатор. и с остальным тоже. просто было интересно с академической точки зрения.
while true;
Re[2]: глобальные переменные
От: ra88  
Дата: 20.01.09 22:42
Оценка:
A>Неправильно поставлен вопрос. О быстродействии на этом этапе заботиться еще рано. Вопрос должен звучать так: как организовать код чтобы сделать его максимально простым, понятным и легко сопровождаемым.

это уже другой вопрос. меня в данном случае интересовал именно первый (опять же больше теоретически)

A>Я бы предложил тебе сделать my_type классом, а do_something1/do_something2 — методами класса. Тогда тебе, во-первых, не прийдется оперировать глобальными объектами, и, во-вторых, твой код будет чище и понятнее, чем, когда ты просто структуру пихаешь в параметры функций.


забыл указать, что рабтаю в С (gcc-4.3.2)
while true;
Re[2]: глобальные переменные
От: ra88  
Дата: 20.01.09 22:45
Оценка:
R>Вы совершаете типичную для начинающего программиста ошибку: все свое внимание сосредотачиваете на быстродействии, забывая о гораздо более важных аспектах программирования, таких как, надежность программ, простота и понятность кода, расширяемость, сопровождаемость, тестопригодность и т.д. Те моменты, которым Вы сейчас уделяете столько внимания, вероятнее всего никогда не будут узким горлышком Вашей программы. Мой Вам совет: начните с чтения книжек, Вы очень быстро поймете, что гораздо проще правильную программу сделать быстрой, чем быструю правильной.

R>


спасибо за совет. Но интересовал вопрос именно в той постановке, которую я использовал. Думаю, что теперь разобрался.
while true;
Re[5]: Какой язык имеется в виду? Видимо С++?
От: Erop Россия  
Дата: 21.01.09 09:16
Оценка: 1 (1)
Здравствуйте, ra88, Вы писали:

R>извиняюсь ещё раз. первое и второе указал вроде бы в ответе, третье думал следует из контекста, но на всякий случай

Прошу прощения, не понял надпись в скобочках

ещё раз:
R>1) С
R>2) gcc-4.3.2
R>3) linux
Спасибо. Теперь стало понятнее.

R>спасибо, действительно не знал такого слова. К сожалению, в моём случае структура выглядит несколько сложнее и неконстантная, т.е. она может принимать различные состояния.


Ну всё равно структуры часто можно агрегатами инициализировать. Правда в C, кажется, только константными выражениями...

R>Тем не менее многое прояснилось. Думаю, что справедливо полагать, что первый вариант должен быть быстрее. GCC переводит статическую структуру в данном случае в заклинание типа

R>
R> 98     .local  my_var
R> 99     .comm   my_var,16,16
R>

R>что на сколько я понимаю означает, что резервируется память в (в данном случае) в 16 байт с соответствующиим выравниванием и закрепляется за my_var, который потом и используется в коде.

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

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

Так что точный ответ про быстродействие на самом деле может дать только тест...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: глобальные переменные
От: MasterZiv СССР  
Дата: 23.01.09 15:55
Оценка:
ra88 пишет:

> Вопрос: Есть ли какое-то преимущество одного из методов с точки зрения

> быстродействия?

Очень маленькое у варианта с глобальными переменными.
Параметр не пихается в стек. Это конечно если он на данной платформе есть.

> Во втором варианте вроде бы более или менее понятно. При вызове функции

> адрес структуры помещается в регистер,

в стек чаще всего.

вызывается цалл и функция берёт
> адрес из регистра.

> Что происходит в первом варианте?

в функцию просто в код прошивается константное значение — адрес этой вашей
глобальной переменной.

на практике лучше вариант с параметром. Так обеспечивается большая
гибкость кода — если завтра переменных будет несколько, эта ваша
функция этого не заметит.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: глобальные переменные
От: MasterZiv СССР  
Дата: 23.01.09 15:58
Оценка:
Erop пишет:

> А ты уверен, что это плюсы?

А что, есть разница ?
Posted via RSDN NNTP Server 2.1 beta
Re[3]: глобальные переменные
От: Аноним  
Дата: 23.01.09 19:46
Оценка:
Здравствуйте, ra88, Вы писали:

R>согласен про оптимизатор. и с остальным тоже. просто было интересно с академической точки зрения.


На академию этот вопрос вообще не тянет.
Разница если и есть, то ею можно пренебречь и больше
позаботиться об удобстве использования и последующиего сопровождения.
Re[4]: глобальные переменные
От: Erop Россия  
Дата: 23.01.09 20:03
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>А что, есть разница ?

А что, в С есть классы?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: глобальные переменные
От: ra88  
Дата: 26.01.09 22:50
Оценка: +1
А>На академию этот вопрос вообще не тянет.
А>Разница если и есть, то ею можно пренебречь и больше
А>позаботиться об удобстве использования и последующиего сопровождения.
всегда удивляют люди, которые на конкретный вопрос пытаются впарить своё мнение на все жизненные темы сразу.
while true;
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.