Функция 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 '; игнорируется », завершив сборник, но по мере того, как часть оптимизации была проигнорирована, то результаты эталона сохранялись в том же диапазоне ( Нет единого улучшения):
О флагах я попробовал с более чем 10 вариантами, но я помесчу одну из них, чтобы иметь общую идею:
sstrong>cpp_funcs_o_setup.py
:
'''
The next is not the current Cython setup file.

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 = '/O1'
else:
compile_args = '-O1'

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»