информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
За кого нас держат?Страшный баг в WindowsSpanning Tree Protocol: недокументированное применение
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Три миллиона электронных замков... 
 Doom на газонокосилках 
 Умер Никлаус Вирт 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
[C++] Оптимизацию выключать нельзя, потому что использутся шаблоны 05.02.02 22:34  Число просмотров: 909
Автор: leo <Леонид Юрьев> Статус: Elderman
<"чистая" ссылка>
<programming>
[C++] Ну все, спасайте меня :-) MS VC++ 7.0 05.02.02 09:58  
Автор: leo <Леонид Юрьев> Статус: Elderman
<"чистая" ссылка>
Есть такой зверь MS Visual Studio .NET beta2, а в нем VC++ 7.0...
Компилятор там точно нормальный, потому что немного старше своего "брата" из WinXP DDK.

Суть борьбы вот в чем:
Нужно заставить компилятор не "свертывать" чтение по указателю, результат которого не используется. Например имеем код:
void MyFunc(volatile unsigned *MyPtr)
{
  unsigned dummy;
  dummy = *MyPtr;
  dummy = *MyPtr;
}

---
При полной оптимизации (/Oxa) компилятор убивает обращения к *MyPtr, а их нужно оставить. Потому что MyPtr указывает на Memory Mapped I/O Space и чтение *MyPtr аналогично __asm in al, dx

До включения полной потимизации было достаточно volatile-спецификатора, что сейчас делать не знаю. Конечно можно тупо написать функцию чтения, но в данном случае нужно максимально быстро, и затраты на вызов функции существенны.

Было-бы интересно узнать, как указать компилятору что функция (или выражение) имеет некий side-effect и не допускает удаления, как например _inp(). Например GCC имеет для этого все средства...
[C++] Ну все, спасайте меня :-) MS VC++ 7.0 05.02.02 22:02  
Автор: + <Mikhail> Статус: Elderman
<"чистая" ссылка>
A eto ne rabotaet?
#pragma optimize( "", off )
 void MyFunc(volatile unsigned *MyPtr)
 {
   unsigned dummy;
   dummy = *MyPtr;
   dummy = *MyPtr;
 }
#pragma optimize( "", on ) 

---
[C++] Оптимизацию выключать нельзя, потому что использутся шаблоны 05.02.02 22:34  
Автор: leo <Леонид Юрьев> Статус: Elderman
<"чистая" ссылка>
[C++] Оптимизацию выключать нельзя, потому что использутся шаблоны 05.02.02 23:31  
Автор: + <Mikhail> Статус: Elderman
<"чистая" ссылка>
Ne vizhu ni kakoi sviazi.
No a esli vse zhe nastaivaesh togda bot tak:

 void MyFunc(volatile unsigned *MyPtr)
 {
   unsigned dummy;
#pragma optimize( "", off )
   dummy = *MyPtr;
   dummy = *MyPtr;
#pragma optimize( "", on ) 
 }

---
[C++] Извините, но это все фигня 06.02.02 10:10  
Автор: leo <Леонид Юрьев> Статус: Elderman
<"чистая" ссылка>
1) RTFM - #pragma допустима только вне функции, вне декларации, вне шаблона;
2) RTFM - При глобальной "Whole Program Optimization" компилятор все равно убьет все функции без сторонних эффектов, результат которых не используеться;
3) RTFM - чтобы гарантированно выключить оптимизацию в шаблоне, ее нужно выключить везде где этот шаблон используется;

Оптимизацию выключать вообще не выгодно и не удобно. Лучше сделать несколько внешних (недоступных) оптимзатору функций, которые будут выполнять чтение или "делать вид" использования результата. Пока я так и сделал: volatile-чтения, результат которых не используется, сейчас передается параметром в недоступную оптимизатору dummy-функцию .
Это решение не нравится прежде всего тем, что вызов внешней функции(равно как и __asm-вставка) заставляет компилятор перезагружать значение регистров их памяти, и в итоге увеличивае размер кода в ~5 раз.

Хотелось бы перевести обсуждение в другое "русло", не как выключить оптимизацию, а как указать оптимизатору что чтение из памяти имеет сторонний эффект.
[C++] Извините, но это все фигня 06.02.02 17:48  
Автор: cb <cb> Статус: Member
<"чистая" ссылка>
> Хотелось бы перевести обсуждение в другое "русло", не как
> выключить оптимизацию, а как указать оптимизатору
> что чтение из памяти имеет сторонний эффект
.

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

void MyFunc(volatile unsigned *MyPtr)
{
  unsigned dummy;
  dummy = *MyPtr;
  dummy ^= dummy;
  dummy |= *MyPtr;
}

---
[C++] Извините, но ещё фигня 08.02.02 02:49  
Автор: Biasha <Бяша> Статус: Member
<"чистая" ссылка>
А ещё можно вот так:
void MyFunc(volatile unsigned *MyPtr)
{
	unsigned dummy;
	for(dummy = *MyPtr;dummy = *MyPtr;)
		break;
}

---
или так:
void MyFunc(volatile unsigned *MyPtr)
{
	unsigned dummy;
	dummy = *MyPtr;
	{dummy = *MyPtr;}
}

---
Только, к сожалению, всё это благодаря ограниченности интеллекта оптимизатора, а значит может и не работать на следующих его версиях.
[C++] Оптимизатор VC++ 7.0 все это "кушает" 08.02.02 07:26  
Автор: leo <Леонид Юрьев> Статус: Elderman
<"чистая" ссылка>
[C++] Ну все, спасайте меня :-) MS VC++ 7.0 05.02.02 13:30  
Автор: cb <cb> Статус: Member
<"чистая" ссылка>
> к *MyPtr, а их нужно оставить. Потому что MyPtr указывает
> на Memory Mapped I/O Space и чтение *MyPtr аналогично __asm
> in al, dx

а на сколько принципиально использование именно Memory Mapped I/O Space? может быть можно обойтись именно in al, dx?

cb.
[C++] Это все разговоры, а нужно решение 05.02.02 14:24  
Автор: leo <Леонид Юрьев> Статус: Elderman
<"чистая" ссылка>
> а на сколько принципиально использование именно Memory
> Mapped I/O Space? может быть можно обойтись именно in al,
> dx?

Во-первых: Memory Mapped I/O работает со скоросью шины (PCI/AGP и т.д.), а Port I/O со скоротью ISA. А мне именно скорость и нужна.

Во-вторых: не переделывать ведь железку из-за dummy-компилятора :-)
[C++] Это все разговоры, а нужно решение 05.02.02 14:40  
Автор: cb <cb> Статус: Member
<"чистая" ссылка>
а что это уже не работает?

#pragma optimize( "", off )
.
.
.
#pragma optimize( "", on )
[C++] Re: Это все разговоры, а нужно решение 05.02.02 16:30  
Автор: leo <Леонид Юрьев> Статус: Elderman
<"чистая" ссылка>
Выключение оптимизации конечно даст нужный эффект. Но я использую шаблоны, поэтому если идти этим путем, то выключать потимизаци. нужно вообще...

Сейчас я вызываю внешнюю пустую dummy-функцию, которая кроме RET ничего не далеет.
Примерно так:

    void __fastcall DummyVolatileNoop(const unsigned __int8 dummy);
    void __fastcall DummyVolatileNoop(const unsigned __int16 dummy);
    void __fastcall DummyVolatileNoop(const unsigned __int32 dummy);
    ...

    template <bool MemoryMapped, bool IoPause> class THardwareIo
    {
    public:
    ...
        template <typename type> __forceinline static void CommitVolatileRead(const type Value)
        {
            if(MemoryMapped)
                DummyVolatileNoop(Value);
        }
    ...
   }

   ... 

    template <class THardwareIo> class CL_VGA
    {
    public:

        LyWin2000Kernel::THardwareIoAddress FrameBufferAddress;
        LyWin2000Kernel::THardwareIoAddress BaseIoAddress;
        LyWin2000Kernel::THardwareIoAddress ExRomAddress;
        LyWin2000Kernel::THardwareIoAddress GpioAddress;
      ....

        __forceinline void WriteHiddenDAC(const unsigned __int8 value) const // hirgwr
        {
            THardwareIo::CommitVolatileRead(
                ReadRegisterByte(VGA_VideoDacPixelMask_HiddenDac)
                | ReadRegisterByte(VGA_VideoDacPixelMask_HiddenDac)
                | ReadRegisterByte(VGA_VideoDacPixelMask_HiddenDac)
                | ReadRegisterByte(VGA_VideoDacPixelMask_HiddenDac)
                );
            WriteRegisterByte(VGA_VideoDacPixelMask_HiddenDac, value);
        }

        __forceinline unsigned __int8 ReadHiddenDAC() const // hirgrd
        {
            THardwareIo::CommitVolatileRead(
                ReadRegisterByte(VGA_VideoDacPixelMask_HiddenDac)
                | ReadRegisterByte(VGA_VideoDacPixelMask_HiddenDac)
                | ReadRegisterByte(VGA_VideoDacPixelMask_HiddenDac)
                | ReadRegisterByte(VGA_VideoDacPixelMask_HiddenDac)
                );
            return ReadRegisterByte(VGA_VideoDacPixelMask_HiddenDac);
        }

     ...

// ------------- extern asm-файл

[section .text]

[global ?DummyVolatileNoop@LyWin2000Kernel@@YIXPBX@Z]
[global ?DummyVolatileNoop@LyWin2000Kernel@@YIX_K@Z]
...

[global ?ReadVolatileQuad@LyWin2000Kernel@@YI_KK@Z]
[global ?ReadVolatileLong@LyWin2000Kernel@@YIIK@Z]
[global ?ReadVolatileWord@LyWin2000Kernel@@YIGK@Z]
[global ?ReadVolatileByte@LyWin2000Kernel@@YIEK@Z]

?ReadVolatileByte@LyWin2000Kernel@@YIEK@Z:
	mov	al, [ecx]
?DummyVolatileNoop@LyWin2000Kernel@@YIXPBX@Z:
?DummyVolatileNoop@LyWin2000Kernel@@YIX_K@Z:
...
	ret

?ReadVolatileWord@LyWin2000Kernel@@YIGK@Z:
	mov	ax, [ecx]
	ret

?ReadVolatileLong@LyWin2000Kernel@@YIIK@Z:
	mov	eax, [ecx]
	ret

?ReadVolatileQuad@LyWin2000Kernel@@YI_KK@Z:
	mov	eax, [ecx]
	mov	edx, [ecx + 4]
	ret


---
[C++] Re: Это все разговоры, а нужно решение 05.02.02 16:54  
Автор: cb <cb> Статус: Member
<"чистая" ссылка>
> Выключение оптимизации конечно даст нужный эффект. Но я
> использую шаблоны, поэтому если идти этим путем, то
> выключать потимизаци. нужно вообще...

почему?

cb.
[C++] Скрытые директивы/ключевые слова VC++ 7.0 05.02.02 17:08  
Автор: leo <Леонид Юрьев> Статус: Elderman
<"чистая" ссылка>
> > Выключение оптимизации конечно даст нужный эффект. Но
> я
> > использую шаблоны, поэтому если идти этим путем, то
> > выключать потимизаци. нужно вообще...
>
> почему?
>
> cb.

Переключать оптимизацию внутри шаблона бесполезно. При генерации кода компилятор будет инсталлировать шаблоны с опциями оптимизации актуальными в месте инсталлирования. Вот и получается, что для получения нужного эффекта требуется выключить оптимизацию во всех фалах проекта, которые используют критический шаблон, и делее шаблоны которые используют это шаблон и т.д.
Это неприемлемо, гораздо проще и выгоднее вызвать внешнюю функции для "покрывания" так сказать "неприкрытого" чтения из Memory Mapped I/O Space.

Я надеюсь что кто-нибудь знает как включить доступ к скрытым директивам VC++ 7.0, и как их использовать, например _annonate, __feacpBreak __compileBreak, __pragma(plmn), __pragma(plmf), __pragma(native_caller) и т.д. Их видно в с1.dll
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2024 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach