3 ms·
I believe many (most?) opencv & numpy operations release the GIL. Good point about OpenCV's in-place operations. Sometimes it's tricky/impossible to do that in
by drothlis 6y ago
I believe many (most?) opencv & numpy operations release the GIL.
Good point about OpenCV's in-place operations. Sometimes it's tricky/impossible to do that in numpy if you need to implement something that OpenCV doesn't provide. For example the C code that I linked in my previous comment, we wrote as an optimization of OpenCV's `matchTemplate` when the inputs meet a specific condition (that both input images are the same size). In C we do the multiplications as we iterate over the images and we maintain a rolling sum in a single variable. In numpy you can't really do this, you have to multiply the whole array and then sum the result.
For 720p images our C implementation[1] was 100x faster than our numpy implementation[2], and 10x faster than numba[3].
[1]: https://github.com/stb-tester/stb-tester/blob/v32/_stbt/sqdiff.c https://github.com/stb-tester/stb-tester/blob/v32/_stbt/sqdi...
[2]: https://github.com/stb-tester/stb-tester/pull/566/files#diff-1de54433cec43681b40f20f3393e8629004d4a3b22f7d04814b9799734f293dbR75-R83 https://github.com/stb-tester/stb-tester/pull/566/files#diff...
[3]: https://github.com/stb-tester/stb-tester/pull/566/files#diff-1de54433cec43681b40f20f3393e8629004d4a3b22f7d04814b9799734f293dbR143-R180 https://github.com/stb-tester/stb-tester/pull/566/files#diff...
- mgradowski 6y agoThat's a nice and tidy codebase, real pleasure to read. > I believe many (most?) opencv & numpy operations release the GIL. Any idea how I can determine this? I am prototyping a real time machine vision application targeting 2x720p@240fps and I want to avoid writing any C++ for as long as possible.
- drothlis 6y agoI don't know much about Python's C API, but this is the line in the OpenCV Python bindings that drops the GIL: https://github.com/opencv/opencv/blob/4.5.0/modules/python/src2/cv2.cpp#L123 https://github.com/opencv/opencv/blob/4.5.0/modules/python/s... (see https://docs.python.org/3/c-api/init.html#releasing-the-gil-from-extension-code https://docs.python.org/3/c-api/init.html#releasing-the-gil-... in the Python C API manual). That's only called from the ERRWRAP2 macro here: https://github.com/opencv/opencv/blob/4.5.0/modules/python/src2/cv2.cpp#L158 https://github.com/opencv/opencv/blob/4.5.0/modules/python/s... That macro, in turn, is called from gen_template_func_body in gen2.py: https://github.com/opencv/opencv/blob/4.5.0/modules/python/src2/gen2.py https://github.com/opencv/opencv/blob/4.5.0/modules/python/s... And that seems to be a code generator that is generating the bindings for all the OpenCV functions: https://github.com/opencv/opencv/blob/4.5.0/modules/python/src2/gen2.py#L1096-L1103 https://github.com/opencv/opencv/blob/4.5.0/modules/python/s... As to testing this, on Linux I'd run `atop` to see if your program is using all available CPUs.
- mgradowski 6y agoNice spelunking! If there is hope of avoiding C++ altogether, then I'll try testing it again on something beefier than my laptop. Thanks for taking the time and effort.