#include <stdio.h>
int main( void )
{
int rows = 3 , cols = 3 ;
int x, y;
printf ( "Suppose we have the following bitmap with (x, y) coordinates\n " ) ; printf ( "where x is the column (HORIZONTAL coordinate)\n " ) ; printf ( "and y is the row (VERTICAL coordinate)\n " ) ; printf ( "(0, 0) (1, 0) (2, 0)\n " ) ; printf ( "(0, 1) (1, 1) (2, 1)\n " ) ; printf ( "(0, 2) (1, 2) (2, 2)\n " ) ; printf ( "If it is stored in row-major order, then the pixels go from\n " ) ; printf ( "left to right, top to bottom in memory, in this order:\n " ) ; printf ( "(0, 0) (1, 0) (2, 0) (0, 1) (1, 1) (2, 1) (0, 2) (1, 2) (2, 2) [ROW MAJOR]\n " ) ; printf ( "If it is stored in column-major order, then the order is:\n " ) ; printf ( "(0, 0) (0, 1) (0, 2) (1, 0) (1, 1) (1, 2) (2, 0) (2, 1) (2, 2) [COLUMN MAJOR]\n " ) ; printf ( "Now let's try it!\n \n " ) ;
printf ( "Outer loop = rows, Inner loop = columns:\n \n " ) ; for ( x = 0 ; x < rows; ++ x) // <-- outer
for ( y = 0 ; y < cols; ++ y) // <-- inner
printf ( "\n \n = COLUMN-MAJOR\n \n " ) ;
printf ( "Outer loop = columns, Inner loop = rows:\n \n " ) ; for ( y = 0 ; y < cols; ++ y) // <-- outer
for ( x = 0 ; x < rows; ++ x) // <-- inner
printf ( "\n \n = ROW-MAJOR\n \n " ) ;
printf ( "Therefore the order which best matches the layout of the pixels\n " ) ; printf ( "in memory (and hence performance due to better cache coherency)\n " ) ; printf ( " Outer loop: columns\n " ) ; printf ( " Inner loop: rows\n " ) ;
return 0 ;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CgppbnQgbWFpbih2b2lkKQp7CglpbnQgcm93cyA9IDMsIGNvbHMgPSAzOwoJaW50IHgsIHk7CgkKCXByaW50ZigiU3VwcG9zZSB3ZSBoYXZlIHRoZSBmb2xsb3dpbmcgYml0bWFwIHdpdGggKHgsIHkpIGNvb3JkaW5hdGVzXG4iKTsKCXByaW50Zigid2hlcmUgeCBpcyB0aGUgY29sdW1uIChIT1JJWk9OVEFMIGNvb3JkaW5hdGUpXG4iKTsKCXByaW50ZigiYW5kIHkgaXMgdGhlIHJvdyAoVkVSVElDQUwgY29vcmRpbmF0ZSlcbiIpOwoJcHJpbnRmKCJcbiIpOwoJcHJpbnRmKCIoMCwgMCkgICgxLCAwKSAgKDIsIDApXG4iKTsKCXByaW50ZigiKDAsIDEpICAoMSwgMSkgICgyLCAxKVxuIik7CglwcmludGYoIigwLCAyKSAgKDEsIDIpICAoMiwgMilcbiIpOwoJcHJpbnRmKCJcbiIpOwoJcHJpbnRmKCJJZiBpdCBpcyBzdG9yZWQgaW4gcm93LW1ham9yIG9yZGVyLCB0aGVuIHRoZSBwaXhlbHMgZ28gZnJvbVxuIik7CglwcmludGYoImxlZnQgdG8gcmlnaHQsIHRvcCB0byBib3R0b20gaW4gbWVtb3J5LCBpbiB0aGlzIG9yZGVyOlxuIik7CglwcmludGYoIiAgXG4iKTsKCXByaW50ZigiKDAsIDApICgxLCAwKSAoMiwgMCkgKDAsIDEpICgxLCAxKSAoMiwgMSkgKDAsIDIpICgxLCAyKSAoMiwgMikgICAgW1JPVyBNQUpPUl1cbiIpOwoJcHJpbnRmKCJcbiIpOwoJcHJpbnRmKCJJZiBpdCBpcyBzdG9yZWQgaW4gY29sdW1uLW1ham9yIG9yZGVyLCB0aGVuIHRoZSBvcmRlciBpczpcbiIpOwoJcHJpbnRmKCIgIFxuIik7CglwcmludGYoIigwLCAwKSAoMCwgMSkgKDAsIDIpICgxLCAwKSAoMSwgMSkgKDEsIDIpICgyLCAwKSAoMiwgMSkgKDIsIDIpICAgIFtDT0xVTU4gTUFKT1JdXG4iKTsKCXByaW50ZigiXG4iKTsKCXByaW50ZigiTm93IGxldCdzIHRyeSBpdCFcblxuIik7CgkKCXByaW50ZigiT3V0ZXIgbG9vcCA9IHJvd3MsIElubmVyIGxvb3AgPSBjb2x1bW5zOlxuXG4iKTsKCWZvciAoeCA9IDA7IHggPCByb3dzOyArK3gpIC8vIDwtLSBvdXRlcgoJCWZvciAoeSA9IDA7IHkgPCBjb2xzOyArK3kpIC8vIDwtLSBpbm5lcgoJCQlwcmludGYoIiglZCwgJWQpICIsIHgsIHkpOwoKCXByaW50ZigiXG5cbj0gQ09MVU1OLU1BSk9SXG5cbiIpOwoJcHJpbnRmKCItLS0tXG5cbiIpOwoJCglwcmludGYoIk91dGVyIGxvb3AgPSBjb2x1bW5zLCBJbm5lciBsb29wID0gcm93czpcblxuIik7Cglmb3IgKHkgPSAwOyB5IDwgY29sczsgKyt5KSAvLyA8LS0gb3V0ZXIKCQlmb3IgKHggPSAwOyB4IDwgcm93czsgKyt4KSAvLyA8LS0gaW5uZXIKCQkJcHJpbnRmKCIoJWQsICVkKSAiLCB4LCB5KTsKCQoJcHJpbnRmKCJcblxuPSBST1ctTUFKT1JcblxuIik7CgkKCXByaW50ZigiVGhlcmVmb3JlIHRoZSBvcmRlciB3aGljaCBiZXN0IG1hdGNoZXMgdGhlIGxheW91dCBvZiB0aGUgcGl4ZWxzXG4iKTsKCXByaW50ZigiaW4gbWVtb3J5IChhbmQgaGVuY2UgcGVyZm9ybWFuY2UgZHVlIHRvIGJldHRlciBjYWNoZSBjb2hlcmVuY3kpXG4iKTsKCXByaW50ZigiaXM6XG4iKTsKCXByaW50ZigiICBPdXRlciBsb29wOiBjb2x1bW5zXG4iKTsKCXByaW50ZigiICBJbm5lciBsb29wOiByb3dzXG4iKTsKCQoJcmV0dXJuIDA7Cn0K
stdout
Suppose we have the following bitmap with (x, y) coordinates
where x is the column (HORIZONTAL coordinate)
and y is the row (VERTICAL coordinate)
(0, 0) (1, 0) (2, 0)
(0, 1) (1, 1) (2, 1)
(0, 2) (1, 2) (2, 2)
If it is stored in row-major order, then the pixels go from
left to right, top to bottom in memory, in this order:
(0, 0) (1, 0) (2, 0) (0, 1) (1, 1) (2, 1) (0, 2) (1, 2) (2, 2) [ROW MAJOR]
If it is stored in column-major order, then the order is:
(0, 0) (0, 1) (0, 2) (1, 0) (1, 1) (1, 2) (2, 0) (2, 1) (2, 2) [COLUMN MAJOR]
Now let's try it!
Outer loop = rows, Inner loop = columns:
(0, 0) (0, 1) (0, 2) (1, 0) (1, 1) (1, 2) (2, 0) (2, 1) (2, 2)
= COLUMN-MAJOR
----
Outer loop = columns, Inner loop = rows:
(0, 0) (1, 0) (2, 0) (0, 1) (1, 1) (2, 1) (0, 2) (1, 2) (2, 2)
= ROW-MAJOR
Therefore the order which best matches the layout of the pixels
in memory (and hence performance due to better cache coherency)
is:
Outer loop: columns
Inner loop: rows