Сообщение Re[25]: C# - from indians by indians от 06.06.2015 20:08
Изменено 06.06.2015 21:53 Evgeny.Panasyuk
EP>C++ версия
EP>
EP>UPD: Иногда бывает даже вот так:
EP>
Исходный main:
А вот main из .js отформатированный сторонней утилитой. Имена идентификаторов это то что я разревёрсил, до этого были одно-двух буквенные:
mem_as_Int32 и mem_as_Float64 это views одного и того же буфера (есть views и других типов). Heap и stack находятся в этом буфере.
Первый цикл это generate_n:
Следующий цикл это transform с легко узнаваемой формулой умножения комплексных чисел:
Несмотря на volatile, компилятор выкинул accumulate. Его можно принудительно добавить (через вывод в результата в cout), но на замер времени это не повлияло.
P.S. Думаю на базе Emscripten можно сделать компилятор из C++ в Java — тогда там наконец "появятся" автоматические структуры
Автор: Evgeny.Panasyuk
Дата: 02.06.15
скомпилированная в JavaScript и запущенная в Firefox:Дата: 02.06.15
EP>
EP>EP>Elapsed = 0.0960432s
EP>UPD: Иногда бывает даже вот так:
EP>
EP>Elapsed = 0.0744424s
Исходный main:
int main()
{
constexpr auto N = 1u << 24;
vector<Complex> v, u;
v.reserve(N);
generate_n(back_inserter(v), N, random_complex);
u = v;
random_shuffle(begin(v), end(v));
random_shuffle(begin(u), end(u));
benchmark([&]
{
transform(begin(v), end(v), begin(u), begin(v), [](auto x, auto y) { return x*y; });
});
volatile auto anti_opti = accumulate(begin(v), end(v), Complex{});
(void)anti_opti;
}
А вот main из .js отформатированный сторонней утилитой. Имена идентификаторов это то что я разревёрсил, до этого были одно-двух буквенные:
JS | |
| |
Первый цикл это generate_n:
e = j + 8 | 0;
b = 16777216;
do {
t = +(rand() | 0) / 1.0e3 + -1.0e3;
mem_as_Float64[j >> 3] = t;
t = +(rand() | 0) / 1.0e3 + -1.0e3;
mem_as_Float64[e >> 3] = t;
a = mem_as_Int32[q >> 2] | 0;
if (a >>> 0 < (mem_as_Int32[h >> 2] | 0) >>> 0) {
if (!a) a = 0;
else {
mem_as_Int32[a + 0 >> 2] = mem_as_Int32[j + 0 >> 2];
mem_as_Int32[a + 4 >> 2] = mem_as_Int32[j + 4 >> 2];
mem_as_Int32[a + 8 >> 2] = mem_as_Int32[j + 8 >> 2];
mem_as_Int32[a + 12 >> 2] = mem_as_Int32[j + 12 >> 2]
}
mem_as_Int32[q >> 2] = a + 16
} else Dc(o, j);
b = b + -1 | 0
} while ((b | 0) != 0);
Тут видно что компилятор в этот же цикл сразу поместил копирование во второй вектор, то есть:generate_n(back_inserter(v), N, random_complex);
u = v;
избежав двух проходов по памяти первого вектора.Следующий цикл это transform с легко узнаваемой формулой умножения комплексных чисел:
high_resolution_clock::now(i);
a = mem_as_Int32[o >> 2] | 0;
c = mem_as_Int32[q >> 2] | 0;
if ((a | 0) != (c | 0)) {
b = mem_as_Int32[m >> 2] | 0;
while (1) {
u = +mem_as_Float64[a >> 3];
g = a + 8 | 0;
w = +mem_as_Float64[g >> 3];
v = +mem_as_Float64[b >> 3];
t = +mem_as_Float64[b + 8 >> 3];
mem_as_Float64[a >> 3] = u * v - w * t;
mem_as_Float64[g >> 3] = w * v + u * t;
a = a + 16 | 0;
if ((a | 0) == (c | 0)) break;
else b = b + 16 | 0
}
}
high_resolution_clock::now(l);
То есть это результат компиляции:transform(begin(v), end(v), begin(u), begin(v), [](auto x, auto y) { return x*y; });
Несмотря на volatile, компилятор выкинул accumulate. Его можно принудительно добавить (через вывод в результата в cout), но на замер времени это не повлияло.
P.S. Думаю на базе Emscripten можно сделать компилятор из C++ в Java — тогда там наконец "появятся" автоматические структуры
EP>C++ версия
EP>
EP>UPD: Иногда бывает даже вот так:
EP>
Исходный main:
А вот main из .js отформатированный сторонней утилитой. Имена идентификаторов это то что я разревёрсил, до этого были одно-двух буквенные:
mem_as_Int32 и mem_as_Float64 это views одного и того же буфера (есть views и других типов). Heap и stack находятся в этом буфере.
Первый цикл это generate_n:
Следующий цикл это transform с легко узнаваемой формулой умножения комплексных чисел:
Несмотря на volatile, компилятор выкинул accumulate. Его можно принудительно добавить (через вывод в результата в cout), но на замер времени это не повлияло.
P.S. Думаю на базе Emscripten можно сделать компилятор из C++ в Java — тогда там наконец "появятся" автоматические структуры
UPD: у компилятора есть опция выводить не "сжатый" код:
Автор: Evgeny.Panasyuk
Дата: 02.06.15
скомпилированная в JavaScript и запущенная в Firefox:Дата: 02.06.15
EP>
EP>EP>Elapsed = 0.0960432s
EP>UPD: Иногда бывает даже вот так:
EP>
EP>Elapsed = 0.0744424s
Исходный main:
int main()
{
constexpr auto N = 1u << 24;
vector<Complex> v, u;
v.reserve(N);
generate_n(back_inserter(v), N, random_complex);
u = v;
random_shuffle(begin(v), end(v));
random_shuffle(begin(u), end(u));
benchmark([&]
{
transform(begin(v), end(v), begin(u), begin(v), [](auto x, auto y) { return x*y; });
});
volatile auto anti_opti = accumulate(begin(v), end(v), Complex{});
(void)anti_opti;
}
А вот main из .js отформатированный сторонней утилитой. Имена идентификаторов это то что я разревёрсил, до этого были одно-двух буквенные:
JS | |
| |
Первый цикл это generate_n:
e = j + 8 | 0;
b = 16777216;
do {
t = +(rand() | 0) / 1.0e3 + -1.0e3;
mem_as_Float64[j >> 3] = t;
t = +(rand() | 0) / 1.0e3 + -1.0e3;
mem_as_Float64[e >> 3] = t;
a = mem_as_Int32[q >> 2] | 0;
if (a >>> 0 < (mem_as_Int32[h >> 2] | 0) >>> 0) {
if (!a) a = 0;
else {
mem_as_Int32[a + 0 >> 2] = mem_as_Int32[j + 0 >> 2];
mem_as_Int32[a + 4 >> 2] = mem_as_Int32[j + 4 >> 2];
mem_as_Int32[a + 8 >> 2] = mem_as_Int32[j + 8 >> 2];
mem_as_Int32[a + 12 >> 2] = mem_as_Int32[j + 12 >> 2]
}
mem_as_Int32[q >> 2] = a + 16
} else Dc(o, j);
b = b + -1 | 0
} while ((b | 0) != 0);
Тут видно что компилятор в этот же цикл сразу поместил копирование во второй вектор, то есть:generate_n(back_inserter(v), N, random_complex);
u = v;
избежав двух проходов по памяти первого вектора.Следующий цикл это transform с легко узнаваемой формулой умножения комплексных чисел:
high_resolution_clock::now(i);
a = mem_as_Int32[o >> 2] | 0;
c = mem_as_Int32[q >> 2] | 0;
if ((a | 0) != (c | 0)) {
b = mem_as_Int32[m >> 2] | 0;
while (1) {
u = +mem_as_Float64[a >> 3];
g = a + 8 | 0;
w = +mem_as_Float64[g >> 3];
v = +mem_as_Float64[b >> 3];
t = +mem_as_Float64[b + 8 >> 3];
mem_as_Float64[a >> 3] = u * v - w * t;
mem_as_Float64[g >> 3] = w * v + u * t;
a = a + 16 | 0;
if ((a | 0) == (c | 0)) break;
else b = b + 16 | 0
}
}
high_resolution_clock::now(l);
То есть это результат компиляции:transform(begin(v), end(v), begin(u), begin(v), [](auto x, auto y) { return x*y; });
Несмотря на volatile, компилятор выкинул accumulate. Его можно принудительно добавить (через вывод в результата в cout), но на замер времени это не повлияло.
P.S. Думаю на базе Emscripten можно сделать компилятор из C++ в Java — тогда там наконец "появятся" автоматические структуры
UPD: у компилятора есть опция выводить не "сжатый" код:
main js | |
| |