Pages

Thursday, October 28, 2021

Performance Comparison in multithread environment: robin_hood::unordered_map vs. tbb::concurrent_hash_map

 

robin_hood::unordered_map

robin_hood::unordered_map is said to be among the fastest in replacements for std::unordered_map. Personally I found that both in VS2019 and Ubuntu 20.04 the map reduces about half of the time spent against std::unordered_map. However, considering its birth and origin, in multithreaded environment we need to serialize the access to the hashmap using something like mutex. Or, the angry Lord of Segmentation Fault will fire at you(......).

tbb::concurrent_hash_map

Well, if you're in multithreading environment, you can't avoid this: Intel's proud production, tbb::concurrent_hash_map from oneTBB (Threading Building Block). In multithreaded environment container classes from TBB is quite decent. Certainly, I'm sure Intel devoted the best efforts to TBB, as its performance is about similar to std::unordered_map, if I compare time spent for the operation.

Fastest in Single Thread vs. Optimized for Multithread

One shows the best speed in single thread environment, and the other is optimized for multithreading. Then one thing: what if we apply something like std::shared_mutex to robin_hood::unordered_map? Wouldn't it be faster if there are more read than write?

OK OK. I know it's nerdy, but you know, ....... a lot of programmers are nerds. Right? So I applied that to my current development. The program's read-write ratio is about 3:1, and I applied std::shared_mutex.

The winner? TIE(oops). The time spent for both libraries was about the same or similar.

What's Your Choice?

Anyway it depends(tm), I concluded tbb:concurrent_hash_map is better. I think tbb::concurrent_has_map will show better performance if there are more requests, and you can avoid any mistakes on implementation with with its own syntax for forced data lock.

For some time being, I'd reside on tbb::concurrent_hash_map.

One More Thing: QReadWriteLock vs. std::shared_mutex (C++17)

Oh yeah. Another nerdy test. For this I just had to swap lock/mutex only so I did it too. And unexpectedly, std::shared_mutex won this time. Though the Qt Company and the community did a lot of efforts to optimize QReadWriteLock(e.g. https://codereview.qt-project.org/c/qt/qtbase/+/140322/ and https://woboq.com/blog/qreadwritelock-gets-faster-in-qt57.html), after some years there seems to be better(and standard) alternative.
 
Yet anyway, thanks for your hard work, Qt team!

멀티스레드 환경에서의 성능 비교: robin_hood::unordered_map vs. tbb::concurrent_hash_map

robin_hood::unordered_map

robin_hood::unordered_map은 std::unordered_map을 대체하는 hashmap 중 가장 속력이 빠른 라이브러리로 알려져 있습니다. 제 개인적인 테스트로는 VS2019 및 Ubuntu 20.04 환경 모두에서 std::unordered_map에 대비하여 수행시간이 약 절반 수준으로 줄어들더군요. 하지만 이것도 태생이 태생이라, 멀티스레드에서 사용하기 위해서는 mutex 등을 사용해서 접근을 제어해야 합니다. 안 그랬다간 바로 segmentation fault의 불호령이 떨어집니다(.....).

tbb::concurrent_hash_map

한편, 멀티스레드 환경에 편리하게 사용하기 위한 hashmap이면 역시 인텔의 자랑인 oneTBB (Threading Building Block)의 tbb:concurrent_hash_map을 빼놓을 수가 없습니다. 멀티스레딩 환경에서 접근제어를 신경쓰지 않고 사용하기에는 역시 TBB의 컨테이너 클래스들이 가장 무난하다 하지 않을 수 없겠습니다. 확실히 인텔이 TBB에 신경을 각별히 쓴게 보이는 것이, std::unordered_map과 성능이 거의 비슷합니다. 각 기능별 소요시간이 std::unordered_map과 거의 똑같더군요.

싱글스레드 최속 vs. 멀티스레드 최적

한쪽은 싱글스레드 환경 한정으로 속도면에서는 최강자이고, 다른 한 쪽은 멀티스레딩 환경에서 최적화된 성능을 보여줍니다. 그럼 문득 드는 생각 하나...... robin_hood::unordered_map에다가 std::shared_mutex같은걸 씌우면, 어쩌면 읽기가 쓰기보다 더 많은 환경에서는 oneTBB보다 더 빠를 수도 있지 않을까?

아니 뭐..... 뻘짓인건 알지만, 그래도 길고 짧은건 역시 대봐야 아는 거잖아요? 해서 제가 현재 개발중인 프로그램에 한번 적용해 봤습니다. 해당 프로그램은 읽기와 쓰기 비율이 약 3:1 정도로 추산되고, 접근제어에는 std::shared_mutex를 사용했습니다.

그리고 테스트 결과는...... 승자가 없습니다. robin_hood::unordered_map과 tbb:concurrent_hash_map 모두 소요시간이 비슷하더군요.

당신의 선택은?

프로그램의 구조에 따라 다르겠지만, 전 tbb::concurrent_hash_map이 더 낫겠다는 판단을 내렸습니다. 리소스에 대한 접근 요청이 많아질수록 tbb::concurrent_hash_map이 더 우세할 것 같기도 하고, 고유 문법을 통해 리소스 접근시 data lock을 강제하기 때문에 구현상의 실수가 더 줄어들겠다는 것이 저의 판단입니다.

최소한 당분간 멀티스레드 환경에서는 tbb:concurrent_hash_map을 쓰게 될 것 같네요.

부록: QReadWriteLock vs. std::shared_mutex (C++17)

길고 짧은건 역시 대봐야 합니다. 이왕 하는김에, 저 두 가지 사이에서도 뭔가 속도 차이가 있을까 싶은 생각이 들어서 저 두 가지도 실험해봤습니다. 그리고 여기선 std::shared_mutex가 승리했습니다.
Qt Company와 커뮤니티가 QReadWriteLock을 최적화하기 위해 갖은 노력을 다 하긴 했습니다만(예: https://codereview.qt-project.org/c/qt/qtbase/+/140322/ and https://woboq.com/blog/qreadwritelock-gets-faster-in-qt57.html), 몇년 뒤에 더 좋은-그리고 표준화된- 대안이 나온 것 같네요.
 
뭐 어찌됐건, 전 Qt의 모든 노력과 그 결과물을 존중합니다. 그리고 저 또한 그 위에 얹혀(?) 살고 있기도 하고요(웃음).

Tuesday, July 27, 2021

If clang backend in Qt Creator stops working in Ubuntu 20.04 LTS

Ubutntu 20.04 LTS has Qt Creator  4.11.0 in APT, and if you install this and open a source file you'll encounter continuous error message of  The clangbackend process has finished unexpectedly and was restarted. If you open shell you'll see some additional messages like Error in ClangCodeModelServer::documentsClosed: Document '/path/to/sourcefile.cpp' does not exists!

For more than one year, to avoid the message, I turned off clang code model plugin from the Creator, but today I found a simple solution - downgrade clangd from 10.0(stock default install) to 8.0. What a relief!

Now I can enjoy the powerful help from libclang. :)

Ubuntu 20.04 LTS에서 Qt Creator의 clang backend가 동작하지 않는 경우

Ubuntu 20.04 LTS에서 APT를 사용해서Qt Creator(4.11.0)를 설치하고 소스파일을 열면 clang backend가 The clangbackend process has finished unexpectedly and was restarted. 라는 오류를 띄우면서 인해 계속 재시작을 하는 기현상을 경험할 수 있습니다. 만일 shell에서 Qt Creator를 실행하면 Error in ClangCodeModelServer::documentsClosed: Document '/path/to/sourcefile.cpp' does not exists! 같은 메시지도 함께 나오더군요.

그동안은 저 에러를 회피하려고 clang code model을 꺼놓고 썼는데, 오늘 간만에 맘잡고 이 문제를 붙잡아본 결과 clangd를 10.0에서 8.0으로 내리면 문제가 해결되더군요.

이걸 몰라서 1년을 넘게 clang code model 없이 삽질께나 했습니다(......).

Sunday, May 2, 2021

When Python Language Server is too slow on Qt Creator(Windows)

Nowadays I'm teaching Python to my son. After teaching stuff I found out that now it's the very timing to teach how to use GUI. And what? For me tkinter is too "weak" and I decided to use Qt, which is one of my favorite "weapon."

So I tried Python on Qt Creator. And guess what? Suddenly LPS became the "black sheep." Ctrl-Space doens't work, and according to messages from LPS it takes a few minutes to follow me up for my 3-second typing...... Frankly speaking I was fully disappointed. Does Qt Creator just ignore Python users, though Qt Company says that it officially supports Python?

However, even it was kind of...... strange. If all the users experience the same symptoms like me, then the forum would have already been highly flamed,  but I couldn't find anything.

Well, and all of sudden, I encountered a solution.

  1. Go to Options and select Language Client
  2. Select Python Language Server
  3. Change Startup behavior from Requires an Open file(default) to Start Server per Project
  4. PROFIT!!!

I have no idea why, but now I'm satisfied with overall performance and result. With default configuration from Qt Creator practically I couldn't do anything so that I seriously considered Visual Stuio Code + Qt Designer, but now with Qt Creator on full throttle, I don't have to go workaround

Hope that this small tip helps those who want to develop in Python with Qt Creator.

Qt Creator(Windows)에서 Python Language Server가 너무 느릴때의 조치방법

그러니까...... 아들녀석에게 Python을 가르치다 보니 GUI를 가르칠 타이밍이 되었는데, tkinter는 (최소한 제 입장에서는) 뭔가 너무 많이 빈약해서 제 장기(?) 중 하나인 Qt를 가르치는게 더 낫겠다는 생각이 들더군요. 그래서 Qt Creator를 사용해서 Qt for Python을 가르치려고 했는데, LPS가 너무 느린겁니다. Ctrl-Space는 동작하지도 않고, LPS에서 뿌리는 메시지를 보면 제가 3초만에 친 타이핑을 쫓아가는데 몇 분 이상이 걸리고...... 하여간 대단히 실망스러웠습니다. Python을 공식적으로 지원한다고 해 놓고 정작 Qt Creator에서는 Python 사용자들을 거의 방치하는 건가 하는 생각까지 들더군요.

하지만 한편으로는 그것도 꽤 이상했습니다. 만일 모든 사용자들이 나와 똑같은 상황이라면 분명히 포럼이 쌩난리였을텐데 왜 이렇게 조용하지?

그런데 의외의 지점에서 해결책이 나오더군요. 제가 찾은 해결책은 이렇습니다.

  1. Options에서 Language Client를 선택합니다.
  2. Python Language Server를 선택합니다.
  3. Startup behavior를 "Requires an Open file"에서 "Start Server per Project"로 변경합니다
  4. 끝!

왜 그런지는 잘 모르겠지만 하여간 이렇게 하니 만족스러운 속도가 나오더군요. 사실 Qt Creator의 기본 설정만으로 작업하려고 했을 때에는 전혀 답이 나오지 않아서 Visual Studio Code + Qt Designer 조합으로 가려고 했는데, Qt Creator가 제대로 성능이 나오기 시작한 이상 굳이 이렇게 갈 필요가 없어졌습니다.

혹시나 Qt Creator로 Python 개발하시려는 분들께 도움이 되었길 바랍니다.

Saturday, March 20, 2021

Would no open source LTS for Qt shrink its user base?

It was last year(2020). Qt announced that it won't provide LTS to its open source editions.
https://www.qt.io/blog/qt-offering-changes-2020

And this year(2021), at March 4th, Qt 5.15.3, the first LTS only for commercial users is released.
https://www.qt.io/blog/commercial-lts-qt-5.15.3-released

Of course the replies for this post are under flame war from open source edition users. They say that Qt user base will shrink, the company has started the first nailing to its coffin, ...... and such. Well, the blog evokes flame war from time to time so I'm just watching it with my popcorn.......

But let's sit down and think. Would the policy of "LTS for commercial clients only" shrink the general user base for Qt? In my thought, it's absolute NO. Let me ask you one question to make it clear.

"OK. Say, let's not use Qt. Then what will we use?"

As far as I know, there's no such library which can fully replace Qt in 1 on 1 way. Some features would be able to be replaced, but Qt-only features are not replicable at all(hey, if you think you can replace Qt Quick with Electron, how would you deal with that RAM consumption?), and if you're joining some other ecosystems, chances are that the difficulty for maintenance will rise exponentially. And say, among those "alternatives," which can provide at least a good match in terms of commercial-level documentation and consistency in API structure? wxWidgets? Hey, I saw so many news to migrate from wxWidgets to Qt but not in the opposite way.

Think of it. When a new language is created, one of the external libraries bound to that language ecosystem at the first time is Qt, which shows what Qt is among developers.

Of course I fully understand the "wrath" from the open source community. I see bugs, report them, and even provide patches for them, and my contributions are applied only to commercial buyers? Yes you have your reasons. Yet...... We also have to admit that we're using commercial grade library without charge in return. And you know what? Before 2011, Qt didn't have LTS at all. (on a side note, if you distinguish open source projects to those with LTS and without one, the former will be only a handful of them).
Well, I don't say that it's great to decide not to provide LTS to open source community. I'd say that it's a typical example of monopoly. The problem is that practically there's no competition. And I don't think that the commercial market is big enough for more than two companies can coexist. Let's admit (the harsh) reality. However hard the open source community works, without good financial support(either by companies or from foundations), you need to pour the money for more than years. Do you think that there would be a company to invest more than years to build a good alternative to Qt? I don't thinks so.

Someone said that he can't upgrade the version of Qt because LTS is not provided. Well, I'd say that how would you use a library which doesn't provide LTS at all, regarding your concerns about stability?