необычная идея: где-нить есть подобное?

Тема в разделе "WASM.HEAP", создана пользователем varnie, 23 апр 2009.

  1. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    хай.

    наткнулса на хитрую мысль, и стало интересно, есть ли что-нить подобное в природе, где подобная фича находит применение и вообще, что кто думает по нижеследующей идее, наглядно имеющей место в таком вот коде:

    Код (Text):
    1. void foo(const std::vector<Foo> &data){
    2.  
    3.   std::size_t i = 0, count = data.size();  
    4.   while (i < count){
    5.       boolean found_any_suitable = false;
    6.       for (int j = 0; j < 100; ++j){
    7.           if (check_condition_for_item(data[i], j)){
    8.               ++i;
    9.               do_smth_with_suitable_item(data[i]);
    10.               found_any_suitable = true;
    11.               break;
    12.           }
    13.       }
    14.       if (!ok){  //prevent the infinite loop
    15.          break;
    16.        }
    17.    }
    18. }
    прекрасно видно, что в ситуации, когда мы нашли хотя бы один подходящий элемент, бегая по внутреннему циклу, то по выходу из него условие
    Код (Text):
    1. if (!found){
    2.     break;
    3. }
    становится избыточным, т.к. бесконечного зацикливания в нашей ситуации уже не будет (мы успешно увеличили счетчик внешнего цикла, i).

    отсюда фантастическая идея:
    а нельзя ли как-нить в рантайме при исполнении __нашего вышерасписанного примера__ сказать проге, чтобы для следующей итерации по внешнему циклу мы бы уже крутились в:
    Код (Text):
    1. //начиная уже с последующей итерации i для вышерассматриваемого примера
    2. while (i < count){
    3.       for (int j = 0; j < 100; ++j){
    4.           if (check_condition_for_item(data[i], j)){
    5.               ++i;
    6.               do_smth_with_suitable_item(data[i]);
    7.               break;
    8.           }
    9.       }
    10.    }
    т.е. мы перебросили управление на __новый__ блок кода, в котором уже нет нек. инструкций (объявления переменной found_any_suitable, присвоения ей true в случае найденного элемента по условию, доп. проверки на бесконечный цикл).
    т.е., мы исключаем ставшими излишними инструкции для данного рантайм ситуации.

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

    что скажете? где-нить подобная возможность реализована? спасибо за внимание.
     
  2. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    update:
    по выходу из новой ф-ции к первой ф-ции уже не возвращаемся.
    т.е. во время рантайма "подменяем" текущую исполняемую ф-цию (или же модифицируем сам её код).
     
  3. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    varnie
    В MS VC++ возможно. См. интринсик _AddressOfReturnAddress. В GCC тоже что-то такое есть.
    Но, AFAIK, в современных процах такие оптимизации вредны - подмена адреса возврата собъёт предиктор проца, в результате производительность только ухудшится.
     
  4. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Имхо пример какой-то бред. Надо сделать не while (i < count), а for.

    goto? Есть. ^)
     
  5. deLight

    deLight New Member

    Публикаций:
    0
    Регистрация:
    26 май 2008
    Сообщения:
    879
    varnie
    перемудрил что-то ты.
    усложнил на порядок простую задачу и теперь ищешь выход )
    возможно я что-то не так понял, но имхо изначально все очень бредово.

    кстати, почему после разового инкремента i условие
    Код (Text):
    1.       if (!ok){  //prevent the infinite loop
    2.          break;
    3.        }
    будет избыточным?
    например мы нашли один элемент, удовлетворяющий условию, увеличили i, который по прежнему остался (i < count), и после этого на ++i ни разу не попали. что тогда?
     
  6. deLight

    deLight New Member

    Публикаций:
    0
    Регистрация:
    26 май 2008
    Сообщения:
    879
    green
    подмена адреса не нужна, goto на новый блок кода.
    другой вопрос зачем эти извращения... это да.
     
  7. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    green
    спасибо! посмотрю.
    deLight, Booster
    возможно я неясно сформулировал идею.
    смысл примера в том, что мы переходим к сл. элементу вектора лишь в том случае, когда для текущего элемента вектора было хотя бы единожды выполнено условие (представленное в внутреннем цикле).
    deLight
    упс, угу, я тормознул;)
    имелось ввиду, что мне хочется в случае хотя бы единожды успешно исполнившегося внутреннего условия далее после брейка из внутреннего цикла __убрать__ из тела ф-ции проверку на infinite loop (т.к. она будет уже избыточной), и сразу же прыгнуть на внешний цикл на следующую итерацию.
    если же это условие не соблюлось ниразу, то проверку на infinite loop после брейка из внутреннего цикла оставить.

    короче, смысл в том чтобы в рантайме "переключать" исполняемый код на тот, который наиболее оптимально подходядит для текущей ситуации.
     
  8. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    блин. извините, что-то я перегрелся седне.
    в моём сообщении выше вычеркнуть строки:
    читать в нём все оставшееся.
     
  9. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    continue?
     
  10. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Не, без goto этого не сделать.
     
  11. deLight

    deLight New Member

    Публикаций:
    0
    Регистрация:
    26 май 2008
    Сообщения:
    879
    varnie
    в твоем коде проверка на infinite loop нужна будет всегда, т.к. ++i не гарантирует (i < count) и следовательно while будет циклиться.

    Booster, varnie
    можно. будем сходить с ума вместе?.. я за =)))
    Код (Text):
    1. void foo(const std::vector<Foo> &data){
    2.  
    3.   std::size_t i = 0, count = data.size();  
    4.  
    5.   char longnop[9] = { 0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 }; // 9-byte NOP
    6.  
    7.   PVOID pnop_me;
    8.   DWORD dwOldProt;
    9.  
    10.   __asm  {
    11.     mov eax, nop_me
    12.     mov dword ptr [pnop_me], eax  // nop_me label offset in pnop_me
    13.   }
    14.  
    15.   VirtualProtect(pnop_me, 9, PAGE_EXECUTE_READWRITE, &dwOldProt);
    16.  
    17.   while (i < count){
    18.       boolean found_any_suitable = false;
    19.       for (int j = 0; j < 100; ++j){
    20.           if (check_condition_for_item(data[i], j)){
    21.               ++i;
    22.               do_smth_with_suitable_item(data[i]);
    23.               found_any_suitable = true;
    24.  
    25.         for (int k=0; k<9; k++)
    26.         ((char*)pnop_me)[k] = longnop[k]; // replace cond. check with NOP
    27.  
    28.               break;
    29.           }
    30.       }
    31.  
    32. nop_me:
    33.       if (!ok){  //prevent the infinite loop
    34.          break;
    35.          // 1 additional byte to match longnop size
    36.          __asm nop;
    37.        }
    38.    }
    39. }
     
  12. deLight

    deLight New Member

    Публикаций:
    0
    Регистрация:
    26 май 2008
    Сообщения:
    879
    О переносимости кода, надеюсь, речи не шло...
     
  13. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    deLight
    Жуть.
     
  14. SashaTalakin

    SashaTalakin New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2008
    Сообщения:
    261
    Код (Text):
    1. void (*__function)(params);
    2.  
    3. ...
    4.  
    5. void init_f (params) {
    6.  ...
    7.  
    8.  if (smth) {
    9.    __function = another_f;
    10.  }
    11.  ...
    12. }
    13.  
    14. void another_f (params) {
    15.  ...
    16. }
    17.  
    18. ..
    19.  
    20. __function = init_f;
    21.  
    22. while (condition) {
    23.   __function(params);
    24. }
    Так может быть? Ну только это очень стремно сейчас выглядит как нубский совсем код с т.з. паттернов программир-я, но идея как я понял такая имелась ввиду. Вообще для таких мелких циклов это ненужная оптимизация, да и оптимизация ли вообще.