digitalmars.D.learn - Fast matrix struct
- Ryan (21/21) Dec 14 2014 I'm writing a Matrix struct that I plan to use for some number
- anonymous (12/33) Dec 14 2014 Just a hint about "a LOT of work":
- John Colvin (19/40) Dec 15 2014 There should be no performance hit for using builtin array
I'm writing a Matrix struct that I plan to use for some number crunching, which will be intensive at times. So I want it to be fast. Will I do better by manually managing the memory myself with malloc and free in the constructors/destructor or just using plain D arrays? The manual way I could bypass the GC and bounds checks. I don't need (or want) any of the fancy appending concatenation and the potential slowdowns from the heap allocations that comes with the builtin arrays. But I have to wonder, if I just don't use those features, will it be just as fast with the GC (assuming I compile out the bounds checks with the -release compiler option)? Right now my strategy is to malloc one large chunk of memory in the constructor (and postblit) and treat the 2-d matrix as a 1-d array internally. Then just use pointer arithmetic to access the elements. I know the best way to know is just to test. But writing both versions would take a LOT of work, and I'm looking for guidance about which path will probably be most fruitful. Thanks,
Dec 14 2014
On Sunday, 14 December 2014 at 22:14:55 UTC, Ryan wrote:I'm writing a Matrix struct that I plan to use for some number crunching, which will be intensive at times. So I want it to be fast. Will I do better by manually managing the memory myself with malloc and free in the constructors/destructor or just using plain D arrays? The manual way I could bypass the GC and bounds checks. I don't need (or want) any of the fancy appending concatenation and the potential slowdowns from the heap allocations that comes with the builtin arrays. But I have to wonder, if I just don't use those features, will it be just as fast with the GC (assuming I compile out the bounds checks with the -release compiler option)? Right now my strategy is to malloc one large chunk of memory in the constructor (and postblit) and treat the 2-d matrix as a 1-d array internally. Then just use pointer arithmetic to access the elements. I know the best way to know is just to test. But writing both versions would take a LOT of work, and I'm looking for guidance about which path will probably be most fruitful. Thanks,Just a hint about "a LOT of work": ---------- struct Hop { version(noGC) // defined with a custom compiler switch -version=noGC private T[] arr; else std.container.Array!T arr; } ---------- The GC-free array already exist in the standard library.
Dec 14 2014
On Sunday, 14 December 2014 at 22:14:55 UTC, Ryan wrote:I'm writing a Matrix struct that I plan to use for some number crunching, which will be intensive at times. So I want it to be fast. Will I do better by manually managing the memory myself with malloc and free in the constructors/destructor or just using plain D arrays? The manual way I could bypass the GC and bounds checks. I don't need (or want) any of the fancy appending concatenation and the potential slowdowns from the heap allocations that comes with the builtin arrays. But I have to wonder, if I just don't use those features, will it be just as fast with the GC (assuming I compile out the bounds checks with the -release compiler option)? Right now my strategy is to malloc one large chunk of memory in the constructor (and postblit) and treat the 2-d matrix as a 1-d array internally. Then just use pointer arithmetic to access the elements. I know the best way to know is just to test. But writing both versions would take a LOT of work, and I'm looking for guidance about which path will probably be most fruitful. Thanks,There should be no performance hit for using builtin array indexing if you compile with -noboundscheck or the equivalent for ldc/gdc. The reverse situation is great though ("Huh, that looks garbled" <recompile with bounds checks enabled, run and hit a RangeError> "Oh look, that's where it went wrong"). Even if for some reason you do hit a problem (e.g. you only want to disable bounds checks for one very hot loop) then adding a quick .ptr before your array indexing will mean no check is generated there under any circumstances. Using D's builtin arrays (better referred to as slices) doesn't imply any necessity to use the garbage collector. You can create a slice from any memory you like, including malloc'd memory. Only appending or manually increasing .length will cause the GC to get involved. I would highly recommend them over raw pointers except in very specialised circumstances. std.container.Array is an option, but it historically hasn't been perfect. I'm not sure of the current state of affairs.
Dec 15 2014