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

Программы на C++. Форум разработчиков
Ответить
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>

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

Как указано в комментариях ниже, я пытался включить Флаги об оптимизации компиляции в файле настройки цинтона, надеясь, что обернутая функция C ++ работала еще более эффективной, чем версия Pure Cython, но часть времени произошла, инструкции о флагах были проигнорированы, а другая часть была ошибкой компиляции Полем Когда флаги/флаги были проигнорированы, терминал показал сообщение на пути: «Незначенный вариант»/o2 '; игнорируется », выполнив завершение компиляции, но по мере того, как часть оптимизации была проигнорирована, тогда результаты эталона сохранились в том же диапазоне, Это означает, что нет улучшений во время выполнения функции оберщенной функции C ++: < /p>
О флагах я попробовал с более чем 10 вариантами, но я помесчу одну из них, чтобы иметь общую идею: 
cpp_funcs_o_setup.py[/b]:
'''
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/src/tutorial/parallelization.html#compilation

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', ...  to see if one of them could work.
extra_link_args=[compile_args],
#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],
#extra_link_args=[compile_args],
)
]

setup(
name='cpp_funcs_wrapper',
ext_modules=cythonize(ext_modules),
)
< /code>

[b] обновление 2 < /strong>:

формат команды компиляции: python cpp_funcs_setup.py build_ext - inplace 
и здесь соответствующая информация, показанная в терминале во время процесса компиляции. Это показывает, что Visual Studio автоматически вызывается при работе с файлами выше cython_funcs_setup.py [/b] и cpp_funcs_setup.py :

Код: Выделить всё

...>python cpp_funcs_setup.py build_ext --inplace
C:\...\Python\Python312\Lib\site-packages\setuptools\_distutils\dist.py:261: UserWarning: Unknown distribution option: 'include_path'
warnings.warn(msg)
running build_ext
building 'cpp_funcs_wrapper' extension
"C:\...\... Visual Studio\2022\...\x64\cl.exe" /c /nologo /O2 /W3 /GL /DNDEBUG /MD -IC:\...\Python\Python312\include -IC:\...\Python\Python312\Include  ...  /EHsc /Tpcpp_funcs.cpp /Fobuild\temp.win-amd64-cpython-312\Release\cpp_funcs.obj
...
Generating code
Finished generating code
copying build\lib.win-amd64-cpython-312\cpp_funcs_wrapper.cp312-win_amd64.pyd ->
...
< /code>

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

об оптимизации компиляции, теперь, насколько я вижу , часть, которая была проигнорирована во время процесса компиляции, показанного в терминале, - это содержимое внутри extra_link_args = [...] 
, поэтому часть внутри extra_compile_args = [...] кажется, что Признание, распознавая аргумент /o2 < /code> в файле настройки цинтона, но он не распознает, когда аргумент /o3 < /code> (когда /o3 < /code>, тогда он игнорируется). Я кратко провел несколько тестов с чем -то, как extra_compile_args = ['/o2', '/gl', '/fp: fast', '/ot', '/ob3'] и некоторые варианты, но пока не могли Не вижу никаких изменений в общее время выполнения, так что это следующий шаг для покрытия.

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

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

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

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

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

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