Это во многом связано с производительностью.
Интересный пример - mongodb, использующий движок mmap. O_DIRECT лучше всего использовать, как утверждали другие, где данные вряд ли будут прочитаны в течение некоторого времени. В mongodb журнал базы данных записывается с использованием O_DIRECT, в то время как записи данных и индексов обрабатываются механизмом кеширования страниц (pdflush), потому что, хотя O_DIRECT предлагает меньшую пропускную способность, это также означает меньшую задержку и, следовательно, снижает потерю данных в случае неожиданный сбой (паника ядра, сбой диска или питания). Обратите внимание, что до того, как запись O_DIRECT будет зафиксирована в энергонезависимой памяти, буферизация все еще существует, это просто снижает потери данных.
Другой важной особенностью O_DIRECT является то, что он обеспечивает больший контроль над последовательностью записи. Опять же, это не гарантирует порядок записи (если у вас нет энергонезависимого кэширующего контроллера диска и не используется планировщик fifo, но у них есть свои сложности). Следовательно, хотя mysql использует O_DIRECT для своих данных / индексов, а также для ведения журнала, можно ожидать, что последнее обычно будет выполнено первым.
Но важно помнить, что O_DIRECT нарушает справедливость распределения ресурсов. Одна из причин, по которой ваше приложение ускоряется, заключается в том, что оно замедляет другие вещи.
Лучше использовать макрос препроцессора, который вы можете определить в строке компиляции. Поэтому измените код на:
#ifndef N_MAC
#define N_MAC 10
#endif
const int N = N_MAC;
, а затем скомпилируйте его с помощью:
g++ test.cpp -DN_MAC=$x -o test.o
Блок $ifndef
обеспечивает значение по умолчанию, если вы не используете -DN_MAC
для его переопределения.
Цикл, который у вас есть, кажется, должен работать, он перекомпилирует программу для значений N
, равных 10
и 20
.
Однако.
1 )Если вам нужны все 11 значений от 10 до 20, вместо этого вам придется использовать что-то вроде for x in {10..20}
или for ((x = 10 ; x <= 20 ; x++))
.
2 )Изменение исходного кода дважды кажется немного бесполезным, может быть чище оставить неизменяемую -базовую версию, которую вы затем модифицируете по мере необходимости, т.е.
sed -e 's/const int N = 10;/const int N = '"$x"';/g' base.cpp > test.cpp
g++ -Wall test.cpp -o test
./test
rm test.cpp test
или даже что-то вроде sed -Ee 's/^(const int N =)[^;]*;/\1 '"$x"';/g'
, чтобы полностью игнорировать значение в присваивании.
3 )Не используйте test.o
для исполняемого файла. Расширение .o
намекает на объектный файл, который вы получите, запустив gcc -c test.c
. Кроме того, в данном случае x
содержит только числа, но на всякий случай лучше заключить -в двойные кавычки, как указано выше.
Тем не менее, изменение программы для считывания числа из командной строки вместо перекомпиляции для каждого значения не будет слишком сложным. Это назначит первый аргумент N
, а затем напечатает его (, это в C, но, насколько мне известно, аргументы main
работают аналогично в C++):
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int N = 10;
if (argc > 1) N = atoi(argv[1]);
printf("N: %d\n", N);
return 0;
}