Я пытался проверить, действительно ли мой макрос работает во время компиляции командой md5sum в ubuntu.

Например, с помощью «nvcc -DTEST_MACRO ....» я получил исполняемый файл A. Затем с помощью "nvcc ..." я получил исполняемый файл B. Конечно значения md5 разные. Но я перекомпилировал и снова сгенерировал A. Его md5 отличается от предыдущего.

Я взял чистый код на C ++ и проверил его с помощью g ++, и его значение md5 оказывается одинаковым независимо от того, сколько раз я компилировал. Поэтому я думаю, что в исполняемом файле, созданном nvcc, есть что-то вроде отметки времени.

  • Просто из любопытства, как мне проверить, верна ли моя мысль?
  • В любом случае, как мне проверить, действительно ли «TEST_MACRO» работает в этом случае?
0
Leo 24 Май 2015 в 06:27
Я не знаю, поможет ли это с вашей проблемой, но это довольно хорошая статья о том, что вам может понадобиться сделать с GCC для генерации детерминированно идентичного вывода (даже если вы говорите, что это не проблема для вас с g ++): blog.mindfab.net/ 2013/12 /… Проблемы и методы, обсуждаемые в статье, могут помочь вам найти решение для nvcc.
 – 
Michael Burr
24 Май 2015 в 06:37

1 ответ

Лучший ответ

Я думаю, что эта изменчивость не обязательно связана со встроенной меткой времени, а скорее из-за того, как nvcc создает исполняемые файлы.

nvcc - это драйвер-компилятор, то есть он запускает последовательность команд "под капотом" для компиляции кода. Во время выполнения этой последовательности создаются различные временные файлы со случайно сгенерированными именами файлов. Вы можете понять это, посмотрев на вывод команды компиляции nvcc с добавленным переключателем -v.

Некоторые из этих имен файлов действительно встраиваются в исполняемый файл, и поскольку эти случайно сгенерированные имена файлов меняются от одного вызова команды компиляции nvcc к следующему, результирующий двоичный файл будет отличаться.

Если вы хотите убедиться в этом сами, запустите команду nvcc с добавленным -v. Затем проверьте вывод в конце на предмет имени файла tmpxft.... Затем выполните команду grep для сгенерированного исполняемого файла для этого имени файла, например:

grep tmpxft_0000a76e myexe

(замените tmpxft_0000a76e тем, что появляется в вашем подробном выводе nvcc, и замените myexe фактическим именем вашего исполняемого файла.)

Если вы хотите проверить, действительно ли TEST_MACRO работает, есть несколько вариантов. Наименее навязчивым может быть размещение в теле TEST_MACRO следующей строки:

#ifdef TEST_MACRO
...
#warning TEST_MACRO_COMPILED
...
#endif

И вы должны увидеть это эхом на выходе во время компиляции, если вы укажете -DTEST_MACRO

(Вышеизложенное является полезным методом, позволяющим избежать ошибочного включения макросов отладки и других вещей, которые вам не нужны в производственной / выпускной сборке кода.)

Конечно, вероятно, есть много других возможностей. Если тестовый макрос включает исполняемый код, вы можете поместить в него оператор printf, чтобы увидеть доказательства во время выполнения.

4
Robert Crovella 24 Май 2015 в 07:07
0000a76e в этом примере - это PID nvcc в шестнадцатеричной кодировке.
 – 
Orivej Desh
24 Июл 2019 в 07:48
Как узнать, что это PID nvcc? Я нигде не вижу этого задокументированного. Нам также нужно было сделать nvcc детерминированным и прибегнуть к шестнадцатеричному редактированию строки tmpxft внутри двоичного файла.
 – 
Trevor Hickey
17 Дек 2019 в 22:22
Это недокументировано. Я искал причины недетерминизма, заметил, что это значение, в частности, обычно увеличивается, но остается небольшой константой в новом пространстве имен PID. Позже я обнаружил, что могу полностью исключить строку tmpxft, запустив nvcc с --keep.
 – 
Orivej Desh
24 Дек 2019 в 23:42
Обратите внимание, что если вам нужен nvcc --device-c & --device-link, у него есть еще один источник недетерминизма: когда .cpp не имеет экспортированных символов, вывод зависит от времени модификации источника и текущего рабочего каталога. Наше окончательное решение находится в github.com/catboost/catboost/commit/f39838c3
 – 
Orivej Desh
24 Дек 2019 в 23:52