Pull to refresh

Comments 28

Можно попробовать метапрограммирование функции Аккермана, это уж точно взорвет мозг компиляторам :)
UFO just landed and posted this here
Думаю получится тоже самое — компилятуру не хватит памяти. Весь ресур экспоненциальной функции не выбран — до 263 инстанциорванных функций ещё далеко. Да и кода там побольше будет. Хотя если у Вас получится — с удовольствием полюбопытствую. ;)
А(4, 4) и не надо. А(3, 25) вполне хватит — там значение порядка десятков миллионов.
Несмотря на всю бессмысленность, спортивный интерес требует попробовать выжать больше;)
помню как-то давно, по молодости, пытался «пойдя легким путем» реализовать деление 1024-битных чисел, через шаблон, который «удваивает разрядность», т.е. имея параметром 32х битный тип, шаблон реализовывал деление и ряд других операций на 64х битах, потом 64х битный тип шел параметром следующей инстанциации дающей на выходе 128 бит, итп. Итоговый код для 1024 и 2048 компилировался очень долго на моем тогдашнем P2 ;)
А вы не пробовали получившиеся exe файлы на то, как хорошо они сжимаются архиваторами? Просто ради любопытства праздного, — если там много повторяющихся бинарных последовательностей, то сжаться должен хорошо, и в свою очередь если там их будет много, это говорит о том, что в теории компиляторы могут оптимизировать такой код лучше. (С другой стороны если не сожмется — то это ни о чем не скажет вовсе ;) )
сжатие это палка о двух концах — если сжать такой файл при помощи UPX — то в RAM получим 2 копии — (1) сжатые данные (2) распакованные данные
Нет, я просто для эксперемента, обычным архиватором вроде 7zip или gz, для оценки энтропии кода, так сказать.
ну если таким образом — то конечно не вопрос.
тогда сразу лучше жать PAQ.
Безусловно они хорошо сжимаются. Там большое количество операций add(addsd, addq ...) или nop для первого раздела. Bzip сжал самый большой бинарник c 53MB до 6.6.
Извините, если может глупость спрошу, а strip вы делали бинарникам?
Нет. Не делал — полагал там несколько килобайт. :( Оказалось размер на треть уменьшился. Спасибо.
Немного изменив изначальный вариант:

template<long N> struct Nop {
    static int nop() {
        static const size_t arraySize = 10240;
        static const long a[arraySize] = {N};
        auto t = ::time(nullptr);
        auto i = static_cast<size_t>(static_cast<double>(t) / static_cast<double>(MAX_LONG) * arraySize);
        return Nop<N - 1>::nop() + static_cast<int>(a[i]);
    }
};

template<> struct Nop<0> { static int nop() { return 0; } };

int main() {
    return Nop<10000>::nop();
}


на VC++ 2012 с -O2 получил 400 Мб.

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

решает.
Попробовал этот код для g++, clang++, icpc.
g++ и icpc выдали одинаковый размер в 783MB
clang++ — засегфолтился.

Суммарный рамер массивов — (10240*8*10000)/(1024*1024) == 781MB.
400МБ — наверное, для 32-битной машины.
Да, собирал для 32-битной системы.
Если разрешить статические массивы, то никакие шаблоны не нужны. Вот программа в две строки, которая для g++ -O3 дает файл размером около 1 ГБ:

volatile char A[1000000000] = { 3 };       
int main() { }
Наблюдаем эту проблему при использовании template haskell. С типами всё хорошо, а вот размер исполняемого файла при этом — мегабайт 20-30.
Было бы удивительно увидеть одинаковые глубины рекурсии между обычным компилятором и clang. У них же фундаментальные отличия.
По-хорошему, форк-бомба всё-таки должна быть корекурсивной. Например
#include <vector>
#include <list>

using std::vector;
using std::list;

template<typename T>
int doStuff(T a) {
	return doStuff( vector<T>() ) + doStuff( list<T>() );
}

int main() {
	doStuff<int>(5);
	return 0;
}
Да, пожалуй. Но чтобы оценить возможную «поражающую силу» удобно простую рекурсию задействовать. А это даже компилировать как-то боязно.:) Хотя не — вылетела по памяти как и остальные.
В таком формате форк-бомбы невозможно добиться успешной компиляции.
Вот что пишет автор в начале статьи:
Но давайте вывернем проблему наизнанку и попробуем получить из минимума строк кода исполняемый файл максимально возможного размера.

Если файл не получился — то он никак не подходит под определение «файл максимально возможного размера».
Ок, если мы ставим своей целью файл максимального размера, то согласен, мой вариант не к месту.
Если же мы хотим fork-бомбу, жадно поглощающую все доступные ресурсы, то предложенный код, имхо, имеет право на существование.
Да, если мы хотим просто поглотить доступные ресурсы, то можно и так.
Хотя мне больше нравится вот этот вариант (на 4 значимые строчки меньше):
template <int N> int foo() { return foo<2*N+1>() + foo<2*N+2>(); }
int main() { foo<0>(); }
Sign up to leave a comment.

Articles