In part 1 I suggested that "native" latency tables are too conservative and can be relaxed for some instructions. Indeed, let's look at couple of examples: In c8.txt there is two delays for IMAD - with value 4 and IMAD.WIDE with value 9. In *_2.txt IMAD included in many groups but none reflect 'wide' form, like IMAD_OP = {IMAD,IMADfmalighter_pipe,IMAD32I,IMAD32Ifmalighter_pipe,…
Optimal instructions scheduling is NP-hard task. For this reason almost all compilers implement metaheuristic methods like list scheduling/Gibbons–Muchnick algorithm etc. ptxas is no exception - it also generates non-optimal scheduling, and this opens some opportunity for automatic optimization. Here I want to present scheduling model for SASS, tool for optimization of stall counts for binary…
Official documentation doesn't disclose ConstBank0 ( c[0x0] ) memory layout used at the SASS level for kernel arguments and special registers (like %gridid , %nctaid ) So I've spent last week trying to solve this deceptively simple problem. Names of params are documented in official doc - seems that this time ptxas can't add something new to this list Unfortunately I was unable to find inside…
Parts 1 , 2 & 3 First of all, it should be noted that the mask of instruction attributes has size 20 bytes, so I updated dump for them. structure for this attributes descriptor has size 0xd8 bytes and some fields: mask at offset 0 name of instruction at 0xC8 index at 0xD0 Instructions selecting first by name and then right form by operand types. This means that while the order of the attributes…
While doing some reverse engineering of ptxas I discovered that their lexer was generated by lex in fast mode (lex -f). Knowing that nvidia trying to hide from us as much as possible it would be good to extract what tokens their lexer able to consume. Surprisingly I was unable to find in google solution for this simple task of tokens recovery. And even worse - seems that nobody understand how 40…
Parts 1 & 2 Pseudo instructions Surprise-surprise - some PTX instructions not mapped directly to underlying SASS 1:1. Instead they generate lots of another PTX code. I already extracted their decrypted bodies , so it's time to describe how they connected to specific PTX pseudo instructions There is function somewhere deep inside ptxas which register lots of handlers for dumping real PTX for pseudo…
Part 1 PTX instructions that cicc cannot generate While reverse-engineering Nvidia's compilation pipeline, I extracted the set of PTX instructions that cicc (the CUDA C++ frontend) is capable of emitting. The next logical step is to intersect them with full set of instructions accepted by ptxas - so we could get instructions which cicc just unable to produce. To do this I add to iptx.pl new option…
Disclaimer Highly likely that author is an illiterate, inattentive, and incompetent lazy person with a poor imagination - therefore his hypotheses may be questionable, ideas delusional and his analysis simply incorrect. Also maybe I still haven't mastered ida pro in 28 years so extracted data can be incomplete/have missed parts. As always all code on perl and therefore offends the aesthetic…
After extracting latency table I became curious how good the code produced by ptxas. Projects like CuAsmRL never estimated limits of profit after rescheduling - it's strange and looks even worse than famous "proof left as an exercise to the reader" - what if ptxas generates perfect code and there is just no space for instructions reordering ? So I wrote perl script to measure redundant stalls and…
method 1 requires building of hijacked .so with appropriate LLVM version. I am too lazy for this method 2 cool, but does not work - cicc claims on bad arguments. I've tried many combinations with no luck But hey - we are under linux and can make many hacks, for example check what arguments genuine nvcc passing to cicc. For this I ran nvcc -dc -keep under strace: strace -o c.strace -s 512 -f…
I've add some support of DWARF debug info from nvidia nvcc to my dwarfdump . As everyone knows dwarf is over-complicated, fat and just disgusting - however, nvidia was able to take his nausea to a new level relocs their cuda-gdb does not contains reloc_howto_type for CUDA relocs - it's special kind of bare minimal open-source when they publish as little code as possible. So my implementation…
LLVM Compiler for RISC-V Architecture Describes details of risc-v vectorization support in llvm. It should be noted that the implementation of vector operations in risc-v was done later than in Intel and sve in arm64 - they took into account many flaws (like made explicit masks for vector operations) and were implemented in a much more convenient way from the programmer's point of view On other…
In my first attempt I used latency tables extracted from MD file (located inside nvdisasm) and nothing good came out of it Obvious reason is that real latency table should be located not in disassembler - it must be inside ptxas. But the problem with that file is that it is really huge - in SDK 13 it has size 40Mb. Sure no symbols included This is not surprisingly bcs it contains lots of things:…
I've done some research of libcudadebugger.so internals - seems that it has exactly the same pattern s: functions table returned by GetCUDADebuggerAPI located in .data section so you can patch any callback address and each API function has logger This last fact is strange - while loggers from libcuda.so were used by debugger then who consume logs from debugger itself? Check code to load those…
For some reason cuda-gdb from cuda sdk gives on my machine list of errors like Traceback (most recent call last): File "/usr/share/gdb/python/gdb/__init__.py", line 169, in _auto_load_packages __import__(modname) File "/usr/share/gdb/python/gdb/command/explore.py", line 746, in <module> Explorer.init_env() File "/usr/share/gdb/python/gdb/command/explore.py", line 135, in init_env…
inconvenient cuda-gdb can't automatically processing them - you need explicitly say something like target cudacore /full/path/to/coredump and then type lots of info cuda XXX So last weekend I wrote tool to parse/dump CUDA coredumps and it even works on machine without CUDA SDK (what might be useful if you collect all crash dumps to some centralized storage with help of CUDA_COREDUMP_PIPE) But…
As illustration of ideas from my previous blogpost I made PoC for logging all libcuda.so calls - as the cuda-gdb debugger sees them It just installs own debug handler and receives all messages. Note: only x86_64 linux supported, but logic can be easily extended for x86 32bit and highly likely for arm64 too events generating before each call, so you can't get result of those calls Current handler…
Previous part I've noticed that almost all real API functions has the same prologues like: mov eax, cs:dword_5E14C00 ; unique for each API function mov [rbp+var_D0], 3E7h mov [rbp+var_C0], 0 mov [rbp+var_C8], 0 test eax, eax jz short loc_39603B lea rdi, [rbp+var_C0] call sub_2EE190 ; get data from pthread_getspecific test eax, eax jz loc_396118 loc_396118: lea rbx, aCustreamupdate_5 ;…
The first question that comes to mind when looking at them is "why they are so huge?". For example libcuda.so from cuda 10.1 has size 28Mb and from 13.1 already 96Mb. So I rejected the idea that they are just yet another victims of vibe-coding and made some preliminary RE. The answer is - because they contain in .rodata section lots of CUBIN files for kernel run-time I extracted them ( archive…
Spent couple of days in debugging rare bug in my sass disasm . I tested it on thousands of .cubin files and got bad instruction decoding for one. Btw I never saw papers about testing of disassemblers - compilers like gcc/clang has huge set of tests to detect regressions, so probably I should do the same. The problem is that I periodically add new features and smxx.so files generating every time My…
In these difficult times, no one wants to report bad or simply weak results (and this will destroy this hypocritical civilization). Since this is my personal blog and I am not looking for grants, I don't care. Let's dissect one truly inspiring paper - they employed reinforcement learning and claim that transparently producing 2% to 26% speedup wow, 26% is really excellent result. So I decided to…
Lets continue to compose some useful things based on perl driven Ced . This time I add couple of new options to test script dg.pl for registers reusing What is it at all? Nvidia as usually don't want you to know. It implemented in SASS as set of operand attributes "reuse_src_XX" and located usually in scheduler tables like TABLES_opex_X (more new like reuse_src_e & reuse_src_h are enums of type…
Finally I add registers tracking in my perl sass disasm Now I can do some full-featured analysis of sass - like find candidates pairs of instruction to swap/run them in so called " dual " mode - and all of this in barely 1200 LoC of perl code Let's think what must mean for couple of instructions to be fully independent: they should belong to the same block - like in case of IADD R8, -R3, RZ…
as an illustration of the use of the modules presented in my previous post I made yet another sass disasm - fully written on Perl. It is almost exact copy of my nvd - implemented just in 460 LoC, the only unsupported feature is registers tracking - bcs I still don't make perl binding for it. What it can do better than original nvdisasm: shows LUT operations shows instructions properties /…
After playing a bit with my ced I came to the conclusion that implemented DSL for editing is not enough - like it would be good to have subroutines to patch repeated/similar instructions, check that patched instruction is what I want, patch attributes/ relocs etc In other words, I need full-fledged PL. Although I've read books series "modern compiler implementation" from Andrew Appel and "…