<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Help me understand dimensions, eu, threads. in Intel® oneAPI DPC++/C++ Compiler</title>
    <link>https://community.intel.com/t5/Intel-oneAPI-DPC-C-Compiler/Help-me-understand-dimensions-eu-threads/m-p/1651342#M4256</link>
    <description>&lt;P&gt;I work as a in the field of cybersecurity. I have have a rig at home with Arc 750 cards.&lt;BR /&gt;I have a background as a software developer and I am currently building my own hash cracker.&lt;BR /&gt;At the moment I am working on a brute forcer.&lt;BR /&gt;&lt;BR /&gt;Alphabet, A-Z, a-z + symbols, and digits.&lt;BR /&gt;&lt;BR /&gt;AAAAA&lt;BR /&gt;AAAAB&lt;BR /&gt;AAAAC&lt;BR /&gt;...&lt;BR /&gt;&lt;BR /&gt;In my first version the host(cpu) created a buffer with a couple of million passwords.&lt;BR /&gt;I sent them over to gpu memory&lt;BR /&gt;And let the GPU work on them.&lt;BR /&gt;&lt;BR /&gt;// Pseudo code&lt;BR /&gt;q.memcpy(gpu_buffer,host_buffer)&lt;BR /&gt;q.memcpy(gpu_hash_to_compare, host_hash_tocompare)&lt;BR /&gt;q.Parallel_For (range (0..count), &amp;nbsp;index) {&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;char* key = gpu_buffer[index*16] &amp;nbsp; // fixed size&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;if (gpu_hash_to_compare == calcHash(key) {&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; // Found&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; // STOP processing&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&amp;nbsp;&lt;BR /&gt;}&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;All calculations are independent of each other.&lt;BR /&gt;The GPU is free to distribute work as it pleases.&lt;BR /&gt;&lt;BR /&gt;I have read about dimensions. And that you can have blocks, work-groups.&lt;BR /&gt;That seems useful when you have work that is dependent on each other,&lt;BR /&gt;but when there are blocks that can execute in parallel.&lt;BR /&gt;&lt;BR /&gt;In my case all work-items are independent, so I don't need work-groups?&lt;BR /&gt;&lt;BR /&gt;Within hash-cracking there are mask-attacks. ?u?d?d?u &amp;nbsp;(uppercase, digit, digit, uppercase)&lt;BR /&gt;A11A&amp;nbsp;&lt;BR /&gt;A11B&lt;BR /&gt;A11C&lt;BR /&gt;..&lt;BR /&gt;&lt;BR /&gt;To parallelize it I was going to feed it partial strings.&lt;BR /&gt;A11?&lt;BR /&gt;A12?&lt;BR /&gt;A13?&lt;BR /&gt;A14?&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;And parallelize it on the gpu side with a for-loop.&lt;BR /&gt;Horrible performance!!&lt;BR /&gt;Now I think the performance is related to something about SIMD I was missing out.&lt;BR /&gt;&lt;BR /&gt;After that I read more about dimensions.&lt;BR /&gt;I rewrote the parallel_for loop to use 2 dimensions.&lt;BR /&gt;&lt;BR /&gt;The first dimension is an index to "A11", "A12"&lt;BR /&gt;The second dimension represented the last digit or digits.&lt;BR /&gt;A11A A11B A11C A11D ..&lt;BR /&gt;A12A A12B A12C A12D ..&lt;BR /&gt;A13A A13B A13C A13D ..&lt;BR /&gt;..&amp;nbsp;&lt;BR /&gt;This approach was an order of magnitude faster.&amp;nbsp;&lt;BR /&gt;3 Dimensions didn't make any difference.&lt;BR /&gt;&lt;BR /&gt;I did some more reading on optimization.&lt;BR /&gt;I think I have just scratched the surface.&lt;BR /&gt;If I distribute work properly I will be able to speed up the program.&lt;BR /&gt;But that requires a bit more knowledge about the hardware.&lt;BR /&gt;&lt;BR /&gt;On my Intel Arc a750:&lt;BR /&gt;eu, execution cores 448&lt;BR /&gt;hw_threads_per_eu 8&lt;BR /&gt;&lt;BR /&gt;One way to send a batch job is&lt;BR /&gt;Keys/work_items = 448 * 8 * (some multiple)&lt;BR /&gt;&amp;nbsp;&lt;BR /&gt;But how do I size the dimensions in an optimal way?&lt;BR /&gt;I have looked at some tables for vtune, but there is a missing step for me.&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;At the moment, the fist dimension is the number of keys or partial keys available to process&lt;BR /&gt;To simplify my own algorithm, the second dimension equals the amount of different letters/digits on the last position or the two last positions.&lt;BR /&gt;&lt;BR /&gt;It is a multiple of &amp;nbsp;10, 26, X, 94&lt;BR /&gt;Only_digits = 10&lt;BR /&gt;Uppercase= 26&lt;BR /&gt;All_letters_and_symbols = 94&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;How does threads works?&lt;BR /&gt;In a normal CPU, the threads are scheduled in on 1 core.&lt;BR /&gt;Do I need to worry about threads at all, or should I just send over a key batch that is a multiple of the number of EU/Execution Units? &amp;nbsp;&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;</description>
    <pubDate>Sat, 21 Dec 2024 18:15:32 GMT</pubDate>
    <dc:creator>mhogstrom</dc:creator>
    <dc:date>2024-12-21T18:15:32Z</dc:date>
    <item>
      <title>Help me understand dimensions, eu, threads.</title>
      <link>https://community.intel.com/t5/Intel-oneAPI-DPC-C-Compiler/Help-me-understand-dimensions-eu-threads/m-p/1651342#M4256</link>
      <description>&lt;P&gt;I work as a in the field of cybersecurity. I have have a rig at home with Arc 750 cards.&lt;BR /&gt;I have a background as a software developer and I am currently building my own hash cracker.&lt;BR /&gt;At the moment I am working on a brute forcer.&lt;BR /&gt;&lt;BR /&gt;Alphabet, A-Z, a-z + symbols, and digits.&lt;BR /&gt;&lt;BR /&gt;AAAAA&lt;BR /&gt;AAAAB&lt;BR /&gt;AAAAC&lt;BR /&gt;...&lt;BR /&gt;&lt;BR /&gt;In my first version the host(cpu) created a buffer with a couple of million passwords.&lt;BR /&gt;I sent them over to gpu memory&lt;BR /&gt;And let the GPU work on them.&lt;BR /&gt;&lt;BR /&gt;// Pseudo code&lt;BR /&gt;q.memcpy(gpu_buffer,host_buffer)&lt;BR /&gt;q.memcpy(gpu_hash_to_compare, host_hash_tocompare)&lt;BR /&gt;q.Parallel_For (range (0..count), &amp;nbsp;index) {&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;char* key = gpu_buffer[index*16] &amp;nbsp; // fixed size&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;if (gpu_hash_to_compare == calcHash(key) {&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; // Found&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; // STOP processing&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&amp;nbsp;&lt;BR /&gt;}&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;All calculations are independent of each other.&lt;BR /&gt;The GPU is free to distribute work as it pleases.&lt;BR /&gt;&lt;BR /&gt;I have read about dimensions. And that you can have blocks, work-groups.&lt;BR /&gt;That seems useful when you have work that is dependent on each other,&lt;BR /&gt;but when there are blocks that can execute in parallel.&lt;BR /&gt;&lt;BR /&gt;In my case all work-items are independent, so I don't need work-groups?&lt;BR /&gt;&lt;BR /&gt;Within hash-cracking there are mask-attacks. ?u?d?d?u &amp;nbsp;(uppercase, digit, digit, uppercase)&lt;BR /&gt;A11A&amp;nbsp;&lt;BR /&gt;A11B&lt;BR /&gt;A11C&lt;BR /&gt;..&lt;BR /&gt;&lt;BR /&gt;To parallelize it I was going to feed it partial strings.&lt;BR /&gt;A11?&lt;BR /&gt;A12?&lt;BR /&gt;A13?&lt;BR /&gt;A14?&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;And parallelize it on the gpu side with a for-loop.&lt;BR /&gt;Horrible performance!!&lt;BR /&gt;Now I think the performance is related to something about SIMD I was missing out.&lt;BR /&gt;&lt;BR /&gt;After that I read more about dimensions.&lt;BR /&gt;I rewrote the parallel_for loop to use 2 dimensions.&lt;BR /&gt;&lt;BR /&gt;The first dimension is an index to "A11", "A12"&lt;BR /&gt;The second dimension represented the last digit or digits.&lt;BR /&gt;A11A A11B A11C A11D ..&lt;BR /&gt;A12A A12B A12C A12D ..&lt;BR /&gt;A13A A13B A13C A13D ..&lt;BR /&gt;..&amp;nbsp;&lt;BR /&gt;This approach was an order of magnitude faster.&amp;nbsp;&lt;BR /&gt;3 Dimensions didn't make any difference.&lt;BR /&gt;&lt;BR /&gt;I did some more reading on optimization.&lt;BR /&gt;I think I have just scratched the surface.&lt;BR /&gt;If I distribute work properly I will be able to speed up the program.&lt;BR /&gt;But that requires a bit more knowledge about the hardware.&lt;BR /&gt;&lt;BR /&gt;On my Intel Arc a750:&lt;BR /&gt;eu, execution cores 448&lt;BR /&gt;hw_threads_per_eu 8&lt;BR /&gt;&lt;BR /&gt;One way to send a batch job is&lt;BR /&gt;Keys/work_items = 448 * 8 * (some multiple)&lt;BR /&gt;&amp;nbsp;&lt;BR /&gt;But how do I size the dimensions in an optimal way?&lt;BR /&gt;I have looked at some tables for vtune, but there is a missing step for me.&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;At the moment, the fist dimension is the number of keys or partial keys available to process&lt;BR /&gt;To simplify my own algorithm, the second dimension equals the amount of different letters/digits on the last position or the two last positions.&lt;BR /&gt;&lt;BR /&gt;It is a multiple of &amp;nbsp;10, 26, X, 94&lt;BR /&gt;Only_digits = 10&lt;BR /&gt;Uppercase= 26&lt;BR /&gt;All_letters_and_symbols = 94&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;How does threads works?&lt;BR /&gt;In a normal CPU, the threads are scheduled in on 1 core.&lt;BR /&gt;Do I need to worry about threads at all, or should I just send over a key batch that is a multiple of the number of EU/Execution Units? &amp;nbsp;&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;</description>
      <pubDate>Sat, 21 Dec 2024 18:15:32 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-oneAPI-DPC-C-Compiler/Help-me-understand-dimensions-eu-threads/m-p/1651342#M4256</guid>
      <dc:creator>mhogstrom</dc:creator>
      <dc:date>2024-12-21T18:15:32Z</dc:date>
    </item>
  </channel>
</rss>

