clang-cl.exe (32bit) dog slow, capping at ~16.5% CPU

I was wondering why compiles were so slow and noticed that clang-cl.exe is never consuming more than ~16.5% CPU on my laptop. This is an i7-7700HQ, 32GB memory, running Windows 10 Pro.

Memory and disk use appear trivial as well, and the computer was otherwise mostly idle at the time.

Compiling a trivial hello-world takes 11 seconds:

$ clang --version

clang version 4.0.1
Target: i686-pc-windows-msvc
Thread model: posix
InstalledDir: C:\LLVM\bin

$ cat foo.cpp

#include

int main()
{
std::cout << “Yo” << std::endl;
return 0;
}

$ time clang-cl foo.cpp

real 0m11.886s
user 0m0.015s
sys 0m0.015s

Compiling the same program under the Linux subsystem and clang-3.5 takes 0.16seconds. The Visual Studio commandline compiler is likewise almost instant.

This is release_40 from one of the git mirrors, build built as part of the LLVM tree using Visual Studio 2015 command prompt, with (I think, not 100% sure, don’t know cmake well enough to figure out after the fact) the following cmake invovations:

cmake -G “MinGW Makefiles”
-DCMAKE_INSTALL_PREFIX=C:\LLVM
-DCMAKE_BUILD_TYPE=Debug
-DLLVM_ENABLE_ASSERTIONS=On
-DLLVM_TARGETS_TO_BUILD=X86
-DLLVM_ENABLE_CXX1Y=On
…/

cmake --build .

Did I pick spectacularly stupid build options or something?

Any suggestions for figuring out what is going on? (Windows is not my regular platform so I’m a bit out of depth here.)

Cheers,

– nikodemus

cmake -G “MinGW Makefiles” \

-DCMAKE_INSTALL_PREFIX=C:\LLVM \

-DCMAKE_BUILD_TYPE=Debug \

-DLLVM_ENABLE_ASSERTIONS=On \

-DLLVM_TARGETS_TO_BUILD=X86 \

-DLLVM_ENABLE_CXX1Y=On \

…/

CMAKE_BUILD_TYPE=Debug will result in a non-optimized compiler. Although I don’t have numbers at hand, you might want to set CMAKE_BUILD_TYPE=Release.

Regards,

Jonas

Is there a way to build LLVM libraries with debug info and clang with release flags?

(I’m working on a frontend toy and figuring out what I’ve done to to crash LLVM is much easier with a debug build…)

If you only need debug information****, you may try RelWithDebInfo.

AFAIK Clang calls into the LLVM libraries. So if you compile those in debug mode, Clang will still be slow even if compiled as Release.

Cheers,

Jonas

Thanks!

I suspect this figure just represents the fact that Clang is using 1/8
cores (plus some help from others for I/O in the OS, perhaps). Even a
debug Clang uses 100% of one core in my experience.

Tim.

cmake -G “MinGW Makefiles” \

-DCMAKE_INSTALL_PREFIX=C:\LLVM \

-DCMAKE_BUILD_TYPE=Debug \

-DLLVM_ENABLE_ASSERTIONS=On \

-DLLVM_TARGETS_TO_BUILD=X86 \

-DLLVM_ENABLE_CXX1Y=On \

…/

CMAKE_BUILD_TYPE=Debug will result in a non-optimized compiler. Although I don’t have numbers at hand, you might want to set CMAKE_BUILD_TYPE=Release.

Also -DLLVM_ENABLE_ASSERTIONS=On

The build system at some point had a warning informing users that this might produce an order of magnitude (or more) slower compiler.

I’d suggest you keep an optimized and unoptimized compiler around. Though even then, Hello World doesn’t take me 10 seconds to compile… so maybe there’s other things going on. Sounds like you’d want one set of LLVM stuff with all the debugging knobs turned on (exactly as you’ve built) & use that with your frontend, and another, release build, for running clang, etc for practical porpoises.

One core out of eight sounds plausible indeed! Never thought of that, more used to *nix style usage numbers where 1.0 = one core. :slight_smile:

Did a release build:

cmake -G “Visual Studio 14 2015”
-DCMAKE_INSTALL_PREFIX=C:\LLVM
-DCMAKE_BUILD_TYPE=Release
-DLLVM_TARGETS_TO_BUILD=X86
-DLLVM_ENABLE_CXX1Y=On
…/

That clang still takes >10s to build a hello-world.

Any suggestions?

Cheers,

– nikodemus

That’s surprising, and not expected. Maybe it depends on what’s in hello world? stdio.h or boost?

I’d profile it and look at it in WPA: https://randomascii.wordpress.com/2015/04/14/uiforetw-windows-performance-made-easier/ This could reveal bottlenecks unique to your system, like AV scanners, network filesystems, or other weird things.

You’ll need a PDB, though, to get anything useful out of it. You can either re-configure and re-build with -DCMAKE_BUILD_TYPE=RelWithDebInfo, or you can try hacking the VS solution to add “/DEBUG” to the clang.exe linker options. Then it will only be a short re-link.

Having previous modified the generated projects before I highly advise against it. It’s tedious, you have to get all of them, and cmake will blow it away the next time you regenerate. You are much better off using RelWithDebugInfo. Note that the last time I generated VS solutions it generated all 3 and I could switch between them. Check if you can just switch your solution’s configuration.

I wonder you specified -DCMAKE_BUILD_TYPE=Release to Visual Studio Generator.

Make sure;

  • Delete CMAKE_BUILD_TYPE
  • clang-cl.exe is generated as Release\bin\clang-cl.exe in your build tree.
    Visual Studio (and msbuild.exe) has multiple configurations.

Aha! Release/bin has just llvm-lit.py in it, whereas Debug/bin has everything. So not a release build after all.

$ grep CMAKE_BUILD_TYPE CMakeCache.txt
CMAKE_BUILD_TYPE:UNINITIALIZED=Release

…which seems odd both for claiming to be uninitialized and not matching the binaries.

So I should delete that line and rebuild with

cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo

?

Cheers,

– nikodemus

Assuming you are using Visual Studio IDE, choose build configuration in toolbar and build again. Debug by default.
CMAKE_BUILD_TYPE should not be set for Visual Studio Generator.

I’ve been building from the command line, the IDE is a foreign land to me, but I’ll give it a try. :slight_smile:

Thanks!

Which tool are you using? msbuild.exe, devenv.exe, or cmake.exe --build ?

With cmake.exe, “cmake --config Release” would be available. (I haven’t tried)

See also; http://bb.pgr.jp/builders/msbuild-llvmclang-x64-msc19-DA/builds/2179/steps/build_llvm_tblgen/logs/stdio

cmake --build

Thank you for assistance!

I can confirm that

cmake --build . --config Release

works. :slight_smile:

Both Release and RelWithDebInfo builds work at reasonable speeds, even with assertions enabled, so I’m a happy camper.

Cheers,

– nikodemus

I recommend ninja.exe if you will not use IDE.
https://ninja-build.org/

Debug configuration with Visual C++ enables expensive iterator checks (_ITERATOR_DEBUG_LEVEL). They do catch bugs sometime.
For example, vector::operator * is:

reference operator*() const
{ // return designated object
#if _ITERATOR_DEBUG_LEVEL == 2
const auto _Mycont = static_cast<const _Myvec *>(this->_Getcont());
if (_Mycont == 0

_Ptr == _Tptr()
_Ptr < _Mycont->_Myfirst
_Mycont->_Mylast <= _Ptr)
{ // report error
_DEBUG_ERROR(“vector iterator not dereferencable”);
_SCL_SECURE_OUT_OF_RANGE;
}

#elif _ITERATOR_DEBUG_LEVEL == 1
_SCL_SECURE_VALIDATE(_Ptr != _Tptr());
const auto _Mycont = static_cast<const _Myvec >(this->_Getcont());
_SCL_SECURE_VALIDATE(_Mycont != 0);
_SCL_SECURE_VALIDATE_RANGE(_Mycont->_Myfirst <= _Ptr && _Ptr < _Mycont->_Mylast);
#endif /
_ITERATOR_DEBUG_LEVEL */

Analysis_assume(_Ptr != _Tptr());

return (*_Ptr);
}

‫בתאריך יום ו׳, 9 ביוני 2017 ב-1:52 מאת ‪NAKAMURA Takumi via cfe-dev‬‏ <‪cfe-dev@lists.llvm.org‬‏>:‬