Функция C ++ (векторы), обернутые цинтоном, примерно в 4 раза медленнее, чем эквивалентная функция цинтона (Numpy MastryPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Функция C ++ (векторы), обернутые цинтоном, примерно в 4 раза медленнее, чем эквивалентная функция цинтона (Numpy Mastry

Сообщение Anonymous »

Имея 2 функции с эквивалентностью алгоритма в обеих сторонах, в c ++ cpp_func1 (обернутый цинтоном) и в cython cython_func1 , быть Основное различие между ними, в котором функция C ++ работает с векторами, и функция цинтона работает с массивом Numpy и MemoryViews, и делая вызовы функций из Python с массивом Numpy из 100 000 элементов, затем при сравнении о времени выполнения, измеренные времена скажем, что вызовы к функции CPP_FUNC1 обернутая функция примерно в 4 раза медленнее в лучшем случае (пожалуйста Посмотрите, как измерить максимальное использование памяти во время каждого выполнения, и если предварительные результаты являются правильными, то вызовы к функции CPP_FUNC1 обернутая функция показывают гораздо более высокое использование памяти (более чем в 3 раза выше, если результаты верны) .
До сих пор реализация cython cython_func1 была той, которая имеет лучшие результаты производительности, и любые предложения по улучшению приветствуются (пока нет, нет Параллелизация цинтона еще протестирована), но о реализации обертки c ++ cpp_func1 с цинтоном, вероятно, мне не хватает важных оптимизаций, и этот вопрос в основном об этом, о том, как у него может быть лучшая производительность . < /p>
Целью сравнения состоит в том, чтобы сравнивать с обеих сторон алгоритм о циклах и контейнерах с приблизительной эквивалентностью, стремясь работать с контейнерами, чтобы избежать копий контейнеров , чтобы быть высокоэффективным при работе с большими контейнерами.cpp_func2 и cython_func2 ) также с петлями и контейнерами, среднее время выполнения в функции CPP_FUNC2 обернутая функция было в 24 раза медленнее, чем цинтона эквивалентная функция .
cython_funcs.pyx:
def cython_func1(double[::1] arr):
cdef int n, m
cdef int window = 5
cdef int len = arr.shape[0] - window + 1
cdef double min_var = 0.0
cdef double max_var = 0.0
cdef double diff_var = 0.0
arr_result = np.zeros(len, dtype=np.double)
cdef double[::1] arr_result_view = arr_result

for n in range(len):
diff_var = 0.0

for m in range(n, (n + window)):
if (m == n):
min_var = arr[m]
max_var = arr[m]
else:
if (arr[m] < min_var):
min_var = arr[m]
elif (arr[m] > max_var):
max_var = arr[m]

diff_var = max_var - min_var
arr_result_view[n] = diff_var

return arr_result

ythonhon_funcs_setup.py:
# Compilation command (CMD):
# python cython_funcs_setup.py build_ext --inplace

from setuptools import setup
from Cython.Build import cythonize
import numpy

setup(
ext_modules = cythonize("cython_funcs.pyx"),
include_path = [numpy.get_include()]
)

cpp_funcs.cpp:
std::vector cpp_func1(const std::vector &vec) {
int window = 5;
int len = vec.size() - window + 1;
double min_var = 0.0;
double max_var = 0.0;
double diff_var = 0.0;
std::vector vec_result(len, 0.0);

for (int n = 0; n < len; n++) {
diff_var = 0.0;

for (int m = n; m < (n + window); m++) {
if (m == n) {
min_var = vec[m];
max_var = vec[m];
}
else {
if (vec[m] < min_var) {
min_var = vec[m];
}
else if (vec[m] > max_var) {
max_var = vec[m];
}
}
}
diff_var = max_var - min_var;
vec_result[n] = diff_var;
}
return vec_result;
}

cpp_funcs.h:
#ifndef CPP_FUNCS_H
#define CPP_FUNCS_H

#include
#include
using namespace std;

std::vector cpp_func1(const std::vector &vec);

#endif

cpp_funcs_wrapper.pyx:
import numpy as np
from libcpp.vector cimport vector

#cdef extern from "cpp_funcs.cpp":
# pass

cdef extern from "cpp_funcs.h":
vector[double] cpp_func1(vector[double] &vec)

def cpp_func1_cython(vector[double] &vec):
return cpp_func1(vec)

cpp_funcs_setup.py:
# Compilation command (CMD):
# python cpp_funcs_setup.py build_ext --inplace

from setuptools import setup
from distutils.extension import Extension
from Cython.Build import cythonize
import numpy

extensions = [Extension("cpp_funcs_wrapper",
["cpp_funcs_wrapper.pyx", "cpp_funcs.cpp"],
language="c++",
#extra_link_args=["-lz"]
)]
setup(
name="cpp_funcs_wrapper",
ext_modules=cythonize(extensions),
include_path = [numpy.get_include()]
)

вызовы из Python :
import cython_funcs
import cpp_funcs_wrapper
import numpy as np
import timeit

arr = np.random.uniform(1, 100000, 100_000)

var1 = timeit.timeit("cython_funcs.cython_func1(arr)", globals=globals(), number=100)
print(f"Average time = {((var1/100) * 1000)} ms.")

var2 = timeit.timeit("cpp_funcs_wrapper.cpp_func1_cython(arr)", globals=globals(), number=100)
print(f"Average time = {((var2/100) * 1000)} ms")
< /code>

Обновление 1 < /strong>:

Как указано в комментариях ниже, я пытался включить Флаги об оптимизации компиляции в файле настройки цинтона, надеясь, что обернутая функция C ++ работала еще более эффективной, чем версия Pure Cython, но часть времени произошла, инструкции о флагах были проигнорированы, а другая часть была ошибкой компиляции Полем Когда флаги/флаги были проигнорированы, терминал показал сообщение на пути: «Незначенный вариант»/o2 '; игнорируется », выполнив завершение компиляции, но по мере того, как часть оптимизации была проигнорирована, тогда результаты эталона сохранились в том же диапазоне, Это означает, что нет улучшений во время выполнения функции оберщенной функции C ++: < /p>
О флагах я попробовал с более чем 10 вариантами, но я помесчу одну из них, чтобы иметь общую идею:
cpp_funcs_o_setup.py
:
'''
The next is not the current Cython setup file, i.e. the
execution time measurements weren't done with the
compilated files produced with this code, and fact the
next hasn't work about performing any optimization. So,
this is just to show what has been tried but never
getting work the part about optimization.

Reference about the next syntax, format, etc.:
https://cython.readthedocs.io/en/stable ... ompilation

All the attempts about compilation optimizations were
only working with the Cython setup file, i.e. not
modifying anything in the command for the compilation.

Compilation command (CMD):
python cpp_funcs_O_setup.py build_ext --inplace
'''

from setuptools import Extension, setup
from Cython.Build import cythonize
import sys
#Also including the part about NumPy when needed.

if sys.platform.startswith("win"):
compile_args = '/O2'
else:
compile_args = '-O2'

ext_modules = [
Extension(
"cpp_funcs_wrapper",
sources=["cpp_funcs_wrapper.pyx", "cpp_funcs.cpp"],
language="c++",
extra_compile_args=[compile_args], # Also for example trying with the next directly here: '/O1', '/O2', '/O3', '/Ofast' '-O1', '-O2', '-O3', ...
extra_link_args=[compile_args],
),
# Also trying to comment/omit the next `Extension` part, and other variants.
Extension(
"cpp_funcs_wrapper",
sources=["cpp_funcs_wrapper.pyx", "cpp_funcs.cpp"],
language="c++",
extra_compile_args=[compile_args],
extra_link_args=[compile_args],
)
]

setup(
name='cpp_funcs_wrapper',
ext_modules=cythonize(ext_modules),
)


Подробнее здесь: https://stackoverflow.com/questions/793 ... -than-equi
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»