<?xml version="1.0" encoding="UTF-8"?>

<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" >

  <channel>
    <title><![CDATA[Комментарии / Профиль cpp_stranger]]></title>
    <link>https://habr.com/ru/users/cpp_stranger/comments/</link>
    <description><![CDATA[Хабр: комментарии пользователя cpp_stranger]]></description>
    <language>ru</language>
    <managingEditor>editor@habr.com</managingEditor>
    <generator>habr.com</generator>
    <pubDate>Wed, 29 Apr 2026 20:10:49 GMT</pubDate>
    
    
      <image>
        <link>https://habr.com/ru/</link>
        <url>https://habrastorage.org/webt/ym/el/wk/ymelwk3zy1gawz4nkejl_-ammtc.png</url>
        <title>Хабр</title>
      </image>
    

    
      

      
        
  
    <item>
      <title>01.11.2020 08:12:06 </title>
      <guid isPermaLink="true">https://habr.com/ru/articles/525892/#comment_22250784</guid>
      <link>https://habr.com/ru/articles/525892/#comment_22250784</link>
      <description><![CDATA[Меня немного удивляет, что никто не хочет указать автору <a href="https://habr.com/ru/users/stalker31/" class="user_link">Stalker31</a> на его ошибки. Попробую это сделать. (Если заметите ошибки и у меня, поправляйте, буду только «ЗА!»).<br>
<br>
Про алгоритм. Вся его суть (без всякой математики по факторизации чисел) сводится к такой реализации: <br>
<pre><code class="cpp">void thread_task(size_t number, size_t max_degree, size_t tid, size_t* result)
{
   // tid - индекс потока
   size_t val = 1;
   for (size_t deg = 1; deg &lt; max_degree; ++deg) {
      val *= tid;
      if (val == number)
         result[tid] = deg;
   }
}</code></pre><br>
Отмечу, что диапазон значений unsigned long long не обязательно хватит для любых входных данных, поэтому не забываем о возможном переполнении.<br>
<br>
Но вернемся к Вашему методу.<br>
Вот вы пишете ожидания завершения потоков:<br>
<pre><code class="cpp">thread *T = new thread[size];
Running_thread_counter = 0;
for (int i = 0; i &lt; size; i++) {
   T[i] = thread(Upload_to_CPU, Number, Stepn, Stop, INPUT, max, i);
   T[i].detach();
}
while (Running_thread_counter &lt; size - 1);//дождаться завершения выполнения всех потоков
// &lt;= только не (size-1), а size

// &lt;= А где у нас удаление ресурсов в виде delete[] T???
</code></pre><br>
<br>
На самом деле, у Вас тут гонка данных (race condition) за общий разделяемый ресурс <blockquote>Running_thread_counter </blockquote>, поскольку каждый поток в Вашей реализации увеличивает эту переменную в самом начале своей работы (а нужно в конце, ибо мы ждем завершения!!!), и никто точно не знает, какое значение осталось в кэше потока. Для более корректного применения такого подхода нужно использовать <pre><code class="cpp">atomic&lt;int&gt; Running_thread_counter</code></pre>, но в идеале я написал бы так: <pre><code class="cpp">for (int i = 0; i &lt; size; i++) {
   T[i] = thread(Upload_to_CPU, Number, Stepn, Stop, INPUT, max, i);
}
for (int i = 0; i &lt; size; i++) {
   T[i].join();   // &lt;= ждем фактического завершения работы потока
}</code></pre><br>
<br>
Неужели Вас совершенно не удивило, что работа 1000 потоков на 8-ми ядерном процессоре быстрее, чем на графическом процессоре, у которого допустимое число потоков куда больше?<br>
<br>
Реализация для графического процессора у Вас просто не подходящая, мягко говоря. Если писать на коленке, то в моем видении, это должно выглядеть примерно так:<br>
<br>
<pre><code class="cpp">__constant__ unsigned long long number, max_degree;
__shared__ unsigned long long buffer[1024];

__global__ void kernel(int* result)
{
   unsigned long long tid = threadId.x;
   unsigned long long val = 1;

   for (unsigned long long deg = 1; deg &lt; max_deg; ++deg) {
      val *= tid;
      if (val == number) {
         buffer[tid] = deg;
         break;
      }
   }
   result[tid] = buffer[tid];
}

int main()
{
   ...
   // CUDA оперирует понятием варпа (cuda core в спецификации видеокарт, 32 потока), 
   // поэтому их число лучше делать кратным 32
   kernel&lt;&lt;&lt;1, 1024&gt;&gt;&gt;();  
   ...
}</code></pre><br>
<br>
Я бы Вам советовал почитать книжки: <br>
<ol>
<li>Энтони Уильямс. «Параллельное программирование на C++ в действии», «C++. Практика многопоточного программирования». </li>
<li>Сандерс Джейсон. Технология CUDA в примерах. Введение в программирование графических процессоров</li>
</ol><br>
Ну и конечно, больше практики. Успехов!<br>]]></description>
      <pubDate>Sun, 01 Nov 2020 08:12:06 GMT</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
    </item>
  

      

      

    
  </channel>
</rss>
