{"action":"created","issue":{"url":"https://api.github.com/repos/libjpeg-turbo/libjpeg-turbo/issues/2","labels_url":"https://api.github.com/repos/libjpeg-turbo/libjpeg-turbo/issues/2/labels{/name}","comments_url":"https://api.github.com/repos/libjpeg-turbo/libjpeg-turbo/issues/2/comments","events_url":"https://api.github.com/repos/libjpeg-turbo/libjpeg-turbo/issues/2/events","html_url":"https://github.com/libjpeg-turbo/libjpeg-turbo/issues/2","id":97571753,"number":2,"title":"AVX2 SIMD support","user":{"login":"dcommander","id":651941,"avatar_url":"https://avatars.githubusercontent.com/u/651941?v=3","gravatar_id":"","url":"https://api.github.com/users/dcommander","html_url":"https://github.com/dcommander","followers_url":"https://api.github.com/users/dcommander/followers","following_url":"https://api.github.com/users/dcommander/following{/other_user}","gists_url":"https://api.github.com/users/dcommander/gists{/gist_id}","starred_url":"https://api.github.com/users/dcommander/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dcommander/subscriptions","organizations_url":"https://api.github.com/users/dcommander/orgs","repos_url":"https://api.github.com/users/dcommander/repos","events_url":"https://api.github.com/users/dcommander/events{/privacy}","received_events_url":"https://api.github.com/users/dcommander/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/libjpeg-turbo/libjpeg-turbo/labels/enhancement","name":"enhancement","color":"84b6eb"},{"url":"https://api.github.com/repos/libjpeg-turbo/libjpeg-turbo/labels/funding%20needed","name":"funding needed","color":"009800"}],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/libjpeg-turbo/libjpeg-turbo/milestones/1","html_url":"https://github.com/libjpeg-turbo/libjpeg-turbo/milestones/libjpeg-turbo%201.5","labels_url":"https://api.github.com/repos/libjpeg-turbo/libjpeg-turbo/milestones/1/labels","id":1228393,"number":1,"title":"libjpeg-turbo 1.5","description":"Desired features for libjpeg-turbo 1.5","creator":{"login":"dcommander","id":651941,"avatar_url":"https://avatars.githubusercontent.com/u/651941?v=3","gravatar_id":"","url":"https://api.github.com/users/dcommander","html_url":"https://github.com/dcommander","followers_url":"https://api.github.com/users/dcommander/followers","following_url":"https://api.github.com/users/dcommander/following{/other_user}","gists_url":"https://api.github.com/users/dcommander/gists{/gist_id}","starred_url":"https://api.github.com/users/dcommander/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dcommander/subscriptions","organizations_url":"https://api.github.com/users/dcommander/orgs","repos_url":"https://api.github.com/users/dcommander/repos","events_url":"https://api.github.com/users/dcommander/events{/privacy}","received_events_url":"https://api.github.com/users/dcommander/received_events","type":"User","site_admin":false},"open_issues":2,"closed_issues":0,"state":"open","created_at":"2015-07-27T22:30:30Z","updated_at":"2015-07-27T22:38:48Z","due_on":null,"closed_at":null},"comments":1,"created_at":"2015-07-27T22:38:48Z","updated_at":"2015-07-27T22:54:16Z","closed_at":null,"body":"Newer Intel/AMD chips provide support for AVX2 (256-bit integer SIMD) instructions, so developing new versions of the libjpeg-turbo SIMD algorithms that take advantage of this technology should improve the performance of libjpeg-turbo (although by how much is unknown.)  Because AVX2 doesn't increase the number of available registers, the best approach is probably to continue using hand-tuned NASM code in order to avoid unexpected register exhaustion.  256-bit SIMD would allow the row multiply operations in the DCT/IDCT algorithms to be executed in a single instruction instead of 3 or 4, and it will allow twice the data parallelism in the color conversion and up/downsampling routines.  What effect this will have on overall performance is unknown.  Huffman coding takes up something like 40-50%, so only 50-60% is available for optimization.  My gut says that we can probably achieve an overall performance boost of about 30% relative to the current SSE2 implementation, which would mean that libjpeg-turbo would be 2.5-7x as fast as libjpeg rather than 2-5x as fast.\r\n"},"comment":{"url":"https://api.github.com/repos/libjpeg-turbo/libjpeg-turbo/issues/comments/125373280","html_url":"https://github.com/libjpeg-turbo/libjpeg-turbo/issues/2#issuecomment-125373280","issue_url":"https://api.github.com/repos/libjpeg-turbo/libjpeg-turbo/issues/2","id":125373280,"user":{"login":"dcommander","id":651941,"avatar_url":"https://avatars.githubusercontent.com/u/651941?v=3","gravatar_id":"","url":"https://api.github.com/users/dcommander","html_url":"https://github.com/dcommander","followers_url":"https://api.github.com/users/dcommander/followers","following_url":"https://api.github.com/users/dcommander/following{/other_user}","gists_url":"https://api.github.com/users/dcommander/gists{/gist_id}","starred_url":"https://api.github.com/users/dcommander/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dcommander/subscriptions","organizations_url":"https://api.github.com/users/dcommander/orgs","repos_url":"https://api.github.com/users/dcommander/repos","events_url":"https://api.github.com/users/dcommander/events{/privacy}","received_events_url":"https://api.github.com/users/dcommander/received_events","type":"User","site_admin":false},"created_at":"2015-07-27T22:54:16Z","updated_at":"2015-07-27T22:54:16Z","body":"Thanks to a generation donation from [Userful](http://userful.com/), I now have a machine that supports AVX2 instructions.  I spent a couple of days in June doing the initial work of adding AVX2 support to the libjpeg-turbo code, and in the process of doing this, I created an AVX2 version of the simplest algorithm (integer quantization.)  I verified that the new AVX2-encoded version of that function is actually being invoked and is producing mathematically correct results, but it's actually slower than its SSE2 counterpart, despite having half the number of instructions.  Further investigation reveals that modern CPU architectures can only read/write 128 bits max at a time, so populating a 256-bit AVX2 register takes more than double the amount of time as it takes to populate a 128-bit SSE2 register. Unless there's enough intermediate compute going on to make up for it, then the overall performance will be slower, despite the compute portion being faster.  The next issue that arises is the fact that the DCT/IDCT algorithms and associated sample conversion algorithm operate on DCT rows and need to compute each row separately.  This is perfect for SSE2, because DCT coefficients are 16-bit when compressing an 8-bit JPEG, and each row is 8 coefficients wide (so 16 bits x 8 = 128 bits.)  Not so perfect for AVX2.  Even discounting the overhead of populating the 256-bit registers, I'm not sure what to do with them once they're populated.  The DCT algorithms tend to be column-parallel, meaning that you can perform the same operation on all 8 coefficients in each row, but the algorithms are not row-parallel.  Different rows are added to each other or subtracted from each other to compute intermediate values, some of which are multiplied by constants and others of which aren't, etc.  Not really any easy way to extend that to 256-bit.\r\n\r\nThis is not to say that AVX2 is useless.  It might be possible to, for instance, accelerate the matrix transpose operation that occurs frequently in the DCT kernels.  It is likely possible to accelerate the color conversion routines as well, since they are more embarrassingly parallel.  AVX2 would certainly provide performance benefits for 12-bit JPEG compression as well, since those algorithms use 32-bit DCT coefficients.  However, I think the takeaway is that this feature will not be as much of a \"slam dunk\" as previously thought.\r\n\r\nOne possible line of research would be to examine some of the other codec projects that are using AVX2 and see how they are leveraging the technology."}}