36

Surprisingly, I haven't found much information on this topic, except for Tips for choosing hardware for best LaTeX compile performance, which states that compilation time mostly depends on how high the clock speed per core of the CPU is.

However, what if I have a lot of graphics (assume both TikZ and PDF figures) and moderately complex text? Can I use a dedicated graphics chip to improve the compilation time?

In general, is there a way to make use of GPU when compiling LaTeX projects?

andselisk
  • 2,675
  • 5
    Doubt it. The sort of processing that is required to compile graphics code is not the sort of process that a graphics card does. – Aubrey Blumsohn Jan 07 '18 at 13:19
  • Not related to GPU usage, but to improve compilation time, you could also use formats (building your own based on your preamble). This way as long as you didn't change your preamble it doesn't have to be compiled again. Especially when you're using big packages (like TikZ) this saves some time. – Skillmon Jan 07 '18 at 13:19
  • 1
    I do not think so, since GPUs are only highly efficient for specific tasks. However if you have a lot of documents parallel compilation on a multicore machine may give some advantage: https://www.uweziegenhagen.de/?p=3501 – Uwe Ziegenhagen Jan 07 '18 at 13:21
  • 3
    Since TeX does not really know anything about graphics instructions of a GPU there is limited advantage of trying to run the TeX compiler on GPU –  Jan 07 '18 at 13:27
  • nah, just select a good package. – mathreadler Jan 07 '18 at 19:09
  • It shouldn't matter much how high the compile time is for the final pdf, and often you only care about intermediate runs to check how some things you added/change affect the overall document. If you have a document where this takes so long, then you might have other options: you could use placeholders (there should be packages for that) for images, or since the document probably is so big, you can split it into multiple parts, so you could compile the parts on their own, which should be near enough to check whatever you want while working on it, and only once in a while do a full compile. – PlasmaHH Jan 08 '18 at 11:57
  • 4
    @UweZiegenhagen You'd be surprised what GPUs can do especially Nvidia Cuda Core programming. https://www.nvidia.com/en-us/data-center/gpu-accelerated-applications/catalog/

    I recently learned it's uses are way more flexible than people think. I'm note 100% sure about LaTeX but I don't think it should be ruled out so quickly.

    – LateralTerminal Jan 08 '18 at 15:14

2 Answers2

27

tikzexternalize in parallel

I thought I might as well expand my answer a bit regarding the parallelization of externalizing tikzpictures. I recommend reading the section of pgfman for more details (p.607 onwards).

Disclaimer: I'm a Linux guy; haven't tried this on other platforms. But this question suggests that it can be done, apparently.

Anyway: Let's make a very simple example document with quite a few tikzpictures in it. Note the mode=list and make in the call to tikzexternalize. That's the important bit.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{external}
\tikzexternalize[prefix=tikz-,mode=list and make]
\begin{document}
\begin{tikzpicture}
    \draw (0,0) -- (1,1);
\end{tikzpicture}
\begin{tikzpicture}
    \draw (1,0) -- (1,1);
\end{tikzpicture}
\begin{tikzpicture}
    \draw (0,2) -- (1,1);
\end{tikzpicture}
\begin{tikzpicture}
    \draw (0,3) -- (1,1);
\end{tikzpicture}
\begin{tikzpicture}
    \draw (0,0) -- (2,1);
\end{tikzpicture}
\begin{tikzpicture}
    \draw (0,0) -- (5,1);
\end{tikzpicture}
\begin{tikzpicture}
    \draw (0,0) -- (2,-1);
\end{tikzpicture}
\begin{tikzpicture}
    \draw (0,0) -- (1,6);
\end{tikzpicture}
\begin{tikzpicture}
    \draw (0,1) -- (7,1);
\end{tikzpicture}
\begin{tikzpicture}
    \draw (0,-1) -- (5,1);
\end{tikzpicture}
\begin{tikzpicture}
    \draw (-1,0) -- (1,0);
\end{tikzpicture}
\end{document}

Run

pdflatex myfile

or your engine of preference.

Then you will have a new file in your directory, myfile.makefile. Execute that with

make -j<PARALLEL_JOB_COUNT> -f myfile.makefile

And that will build your tikzpictures in parallel batches of <PARALLEL_JOB_COUNT> For four, this would be

make -j4 -f myfile.makefile

Use your number of cores as a guideline for how many parallel jobs to run.

If all has gone well, you can then compile your document again and include all the tikzpictures:

pdflatex myfile

And all should be well.

As I mentioned in the comment to TeXnician's answer, I was able to cut down compilation time for my thesis (lots of pgfplots) from about 90 minutes to roughly 13 on a clean directory (well, 16 minutes, actually, counting the two 90-second runs before and after generating the tikzpictures, but still -- pretty impressive gain, methinks). Of course, more cores are better here; I have 12 on that machine.

Aside from compilation time, another thing I found hugely beneficial to this process came about in the workflow though: You can easily force a rebuild of individual tikzpictures from the commandline. If you have your individual tikzpictures in separate files, this means you basically get a very similar workflow as if you'd used standalone for your tikzpictures. So, for example, if we want to build tikz-main-figure5.pdf in this case, we can issue:

make -B -f main.makefile tikz-main-figure5.pdf

The -B option forces make to rebuild the target -- usually needed in these cases if you change your tikzpicture without then compiling your main document again, because then the m5dsum will not get updated and make will think nothing has changed. You can of course also just delete the .pdf file and recompile without the -B switch, but this is how I usually did it during those long hours late at night when I was fiddling with my plots and trying to get them to look right. I had the TikZ pdf open in one window, and the editor with the source code in another, and a shortcut for the recompilation, and that was really quite convenient to work with.


GPU note

Leaving aside the things which have already been mentioned about the compilation of a TeX document being a heavily serialized job in many ways, you would probably need to write your own TeX implementation to run on your GPU, or a wrapper which can run the x86 TeX on your GPU. Neither of these are what I'd call a trivial process, and given that in many scenarios the benefits would probably be marginal (or negative) at best, I doubt it's worth it.


Update: Benchmarks and Background

Since a compile time of 90 minutes seems as ludicrous to me as it probably does to most here, I've dug up the project again and have been fiddling around with it a bit. The current numbers are as follows:

  • Building all tikzpictures from scratch (most of which are pgfplots), sequentially: 57 minutes
  • Building the tikzpictures with 12 jobs in parallel: 7:30 minutes

The whole shebang consists of

  • 61 output pdf files for the tikzpictures
  • 256,000 lines of CSV data, 130,000 of which is 3 columns, the rest mostly 2 columns
  • 237 \addplot commands, the data for which is usually read in via \pgfplotstableread commands

At the moment, I see two primary areas for optimization. Since they are also generally valid for speeding up the compilation of tikzpictures, I hope this is still sufficiently on-topic to mention:

  • Reducing the number of data points, and
  • removing any filter/.code commands, moving their work to the tool which generates the data in the first place.

So:

  • Yes, there is potential for optimization here.
  • I'm fine with that. My point was that parallel compilation of tikzpictures can bring significant reductions in overall compile time and is relatively easy to accomplish if you're not commandline-averse.
  • Also, it's not as bad as it sounds, since I rarely have to compile all tikzpictures from scratch -- usually I just update one thing, and then the whole document compiles in about a 40 seconds (could be further reduced with \includeonly, but I usually don't bother). Or if I'm working on a specific tikzpicture, I only ever need to rebuild that, which is also quite acceptable (see the workflow notes above).

If anyone wants to have a go at it themselves (or be appalled at some LaTeX heresy I probably committed), the document can be found here (full pdf versions available in the snapshots directory). It's a bit of a convoluted setup because I also use a separate build directory and getting that to work properly with tikzexternalize is a bit of a story in and of itself. But if anyone wants to have a look at an actual use-case for a non-tiny project with tikzexternalize, it might be of interest.

alpenwasser
  • 2,455
  • 2
    Out of curiosity, how long does lualatex take to compile your thesis? – Aditya Jan 08 '18 at 04:16
  • 1
    @Aditya Alas, I have not yet been able to make it compile with lualatex (getting an error command \attribute already defined). I have added updated compile times for pdflatex to the post though. – alpenwasser Jan 08 '18 at 14:40
  • 2
    I feel obliged to point out (as you mentioned you're a Linux guy) that you missed a golden opportunity to write "The whole #!" before the second set of bullet points in your update ;-) – tonysdg Jan 08 '18 at 15:43
  • 2
    @tonysdg I considered it, but thought it might feel a bit alienating to those unfamiliar with it. I am quite glad that somebody noticed though. ;-) – alpenwasser Jan 08 '18 at 15:45
  • 3
    Let me say that it is a beautifully typeset thesis! – Aditya Jan 08 '18 at 17:09
  • I'm somewhere between liking and hating your thesis layout. While the plots and most of the rest look very good, I dislike the eye-candy of your chapter titles. They look good but at the same time are annoying :) – Skillmon Jan 08 '18 at 21:41
  • @Skillmon No worries, one's mileage will vary, totally fair enough. It is admittedly rather more decorative than what one usually finds in such documents. While I'm mostly happy with how it came out, if I ever use this code again, I will probably tone it down somewhat to make it less ... intrusive, for lack of a better term. But at some point I had to stop tinkering with the design and actually write the bloody thing (well, my parts of it, anyway). ;-) – alpenwasser Jan 08 '18 at 22:15
  • Wow that is the most beautiful and detailed bachelor thesis I have ever seen, that could easily be a master thesis. – Konrad Höffner Jan 27 '22 at 08:29
25

This question can be understood in two ways:

  1. You want to compile your LaTeX document using CPU and GPU: This is effectively the same question as if you would like to use another core (i.e. multi-core setup) for compiling the document, that's not possible.
  2. You want to use the GPU exclusively: I doubt that this would be highly effective as usually GPUs have some optimized operations, mostly concerning graphics, but are not that much faster for "ordinary" tasks (they may even be slower for some operations). Apart from that it would be a really hard task to use the GPU instead of the CPU as you would need to translate TeX's CPU instructions into GPU instructions beforehand and have your OS (and probably also graphics driver) allow these operations.

What you can do in your situation:

  • If you have many TikZ figures you can use externalization which makes compiling faster (except for the first time). Just including PDFs is very fast.
  • You could also create a format which would "pre-compile" the preamble in some way and therefore speeds things up (except when creating the format, thanks to Skillmon for pointing this out).
TeXnician
  • 33,589
  • Thank you, this clarifies a lot. So, one can theoretically use a single GPU core instead of CPU for compilation? – andselisk Jan 07 '18 at 13:27
  • @andselisk You would have to convince the OS to do so and maybe your graphics driver won't allow it. I have never tried to implement that. – TeXnician Jan 07 '18 at 13:30
  • 2
    @andselisk this wouldn't make sense though. I doubt a single GPU core can be faster than a single CPU core for TeX compilation. – Skillmon Jan 07 '18 at 13:31
  • @Skillmon I agree, hence I put "theoretically":) I'm still wondering what prevents LaTeX compilers from fully using multi-core processors. Then graphics chips would be far more superior since they have much more cores to run in parallel. If you know where I can read about this, please feel free to point me in that direction. – andselisk Jan 07 '18 at 13:34
  • 3
    @andselisk What prevents multi-threading is simple: The page shipout involves many things including counters, page numbers, running headers etc. It would be hard to do this in parallel. If you do not include those parts you can split your document into several ones with a common preamble and then do a multi-threaded compilation (and at the end merge all those), but a normal TeX typesetting process is very linear – TeXnician Jan 07 '18 at 13:36
  • 1
    @andselisk simply think of the time when TeX was created. Also much of the layout depends on stuff computed prior to that, which isn't really the point of multi-threading. – Skillmon Jan 07 '18 at 13:36
  • 3
    You can speed up the process even on the first run with mode=list and make and compiling the tikzpictures in parallel. I reduced first-time compilation of my thesis from about 90 minutes to 13 minutes on a 12-core machine. Compiling the document with all tikzpictures present then takes about another 100 seconds. It's also quite handy because you can build individual tikzpictures manually by just issuing a make <tikzpicture-filename> (might need to be forced if nothing has changed). Gives you basically a standalone-like setup. Unsure on portability though. See p.614f in pgfman. – alpenwasser Jan 07 '18 at 14:13
  • 2
    @alpenwasser I guess the externalization point of first time being not reduced is cpu time which isn't enhanced in your setup either. But introducing make is a good point. Also pre-converting .png files and the like to PDF is a huge improvement (depending on the png file). – Skillmon Jan 07 '18 at 14:27
  • 1
    @alpenwasser 90 minutes to compile?? then you must be doing something very unnecessarily inefficient. – mathreadler Jan 07 '18 at 19:10
  • @mathreadler That might well be, but I'm really not doing anything extravagant. I'm just parsing csv files and plotting the results with pgfplots (which, uhm, might be inefficient?). It's about 140 csv files, 60 tikzpictures and a few hundred thousand data points. Since I rarely had to compile the entire thing from scratch and got excellent output quality, I'm not complaining, though if somebody has suggestions for optimization, I would be curious (though it might be a tad off-topic for this question). – alpenwasser Jan 07 '18 at 22:07
  • 1
    @alpenwasser : Of course if you re-run heavy algorithms to generate all the pictures all the time as part of the script it will take time. Maybe you can decouple the generation of the images from the typesetting process so you only rebuild images if you have changed the process or data dependent on generating them? – mathreadler Jan 08 '18 at 07:25
  • 1
    @mathreadler I have added some new benchmark numbers and background information to my post. Most of the time, the externalized pictures don't change once I've made them, so I actually rarely need to recompile them all. So yes, quite agreed, only regenerating the images when there has been change is advisable (hence using tikzexternalize in the first place). – alpenwasser Jan 08 '18 at 14:54
  • 1
    There’s a misconception in the answer and the comments: you cannot simply substitute the CPU for the GPU. Even if the operating system allowed it. They use different instruction sets and have a different hardware architecture. They don’t speak the same language. In order to run a program on the GPU, it needs to be specifically programmed and compiled to target that GPU. – Konrad Rudolph Jan 08 '18 at 17:49
  • @KonradRudolph Oh well, I see I forgot to add this to the OS and driver comment. Thanks. I'll edit my answer. – TeXnician Jan 08 '18 at 17:58